Skip to content

Instantly share code, notes, and snippets.

@pjambet
Last active January 6, 2020 21:42
Show Gist options
  • Save pjambet/bebddd499ab96070e9ebdd1cc01b2677 to your computer and use it in GitHub Desktop.
Save pjambet/bebddd499ab96070e9ebdd1cc01b2677 to your computer and use it in GitHub Desktop.
Scala Error Handling
val route =
path("order") {
post {
entity(as[OrderRequest]) { orderRequest =>
onComplete(PurchaseService.createPurchase(orderRequest)) {
case Success(result) =>
complete(StatusCodes.Created, result)
case Failure(exception) =>
system.log.error(exception, "Unexpected error")
complete(StatusCodes.InternalServerError,
HttpEntity(ContentTypes.`application/json`,
"{\"error\": true}"))
}
}
}
}
object PurchaseService {
final case class Order(orderId: String)
def createPurchase(orderRequest: OrderRequest)(
implicit ec: ExecutionContext): Future[Order] = {
PaymentClient.chargeCard(orderRequest.cardNumber).map { _ =>
Order(orderId = UUID.randomUUID().toString)
}
}
}
object PaymentClient {
final case class Charge(chargeId: UUID)
sealed trait PaymentException extends Throwable
final class CardException(val declineCode: String) extends PaymentException
final class NotEnoughFundException extends PaymentException
final class UnknownPaymentException extends PaymentException
final class RateLimitException extends PaymentException
final class InvalidRequestException extends PaymentException
final class AuthenticationException extends PaymentException
final class APIConnectionException extends PaymentException
def chargeCard(cardNumber: String)(
implicit ec: ExecutionContext): Future[Charge] = {
// Fake an API call
Future {
if (cardNumber == "valid") {
Charge(UUID.randomUUID())
} else if (cardNumber.startsWith("card_error")) {
val declineCode = cardNumber.split("_").toList.drop(2).mkString("_")
throw new CardException(declineCode)
} else if (cardNumber == "rate_limit_error") {
throw new RateLimitException()
} else if (cardNumber == "invalid_request_error") {
throw new InvalidRequestException()
} else if (cardNumber == "authentication_error") {
throw new AuthenticationException()
} else if (cardNumber == "api_connection_error") {
throw new APIConnectionException()
} else {
throw new UnknownPaymentException()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment