简体   繁体   中英

Modelling exceptions & Handling http codes inside a server application

I am working on a spring boot application, which makes http calls to multiple external services, aggregates and returns the response to the frontend.

Here's the current structure of my project:

RouteController -> Handler -> ServiceLayer
  • RouteController routes to different handlers
  • Handler makes call to multiple services, performs aggregates and returns response.
  • Different ServiceLayers for each service call.
  • Handler can return partial responses, if one service call fails it'll return the response of other calls.
  • I have not added class/controller level exception handler as partial response can also be returned.

Note - This application will always send a Http 200 response, unless all service calls fail.
Spring exception handling https://www.baeldung.com/exception-handling-for-rest-with-spring is for class/controller level and conveys the Http response code to the client. What I'm looking for here is exception handling inside the application.

I'm trying to add exception handling in this service, and there doesn't seem to be a clear concise rule.

This is a custom exception i have created for any dependency failure -

class DependencyException : RuntimeException {
    constructor() : super()
    constructor(message: String?) : super(message)
    constructor(cause: Exception?) : super(cause)
    constructor(message: String?, cause: Exception?) : super(message, cause)
}

Here's the code in service layer making a call to UserService -

fun getUsers(): List<User>? {
        logger.info { "entered: getUsers " }
        val response = userControllerApiClient.getUsers()

        when (response.statusCode.is2xxSuccessful) {
            true -> return response.body?.users
            false ->  throw DependencyException()
        }
    }

Have used org.springframework.http library for http calls.

There are a few questions I couldn't find a clear answer of -

  • When should a service write its own exceptions?
  • When to use kotlin/java standard lib existing exceptions?
  • Should you propagate spring http exceptions to handler/controller layer?
  • Is the scope of dependency exception above too large?
  • Should 4xx,5xx error codes be converted to different custom exception for internal handling? (And also different handling of different codes in each series? )
  • What's the best way you'd recommend for handling exceptions in this project?

Hi for your questions:

  1. When should a service write its own exceptions? -->

it depends in your business logic for example you have a service layer to update a user, you should find it by ID, if user not found you should throw an exception

  1. When to use kotlin/java standard lib existing exceptions?

if you are using spring-boot is a framework to provide for you ready libs and APIS to handle all you can check this link https://www.baeldung.com/exception-handling-for-rest-with-spring

  1. Should you propagate spring Http exceptions to handler/controller layer?

Yes; because the controller is responsible for handling the Http exceptions, the service the business layer

  1. Is the scope of dependency exception above too large?

I didn't understand this question

  1. Should 4xx,5xx error codes be converted to different custom exception types? (And also different handling of different codes in each series? )

No it's not necessary, it's recommended to return the Http error code with custom message for the client to understand exception error cause

  1. What's the best way you'd recommend for handling exceptions in this project?

I recommend following jhiptser spring boot project structure, https://www.jhipster.tech/managing-server-errors/

  1. When should a service write its own exceptions? Whenever existing exceptions in standard library don't cover your use case, or when you want to add more details in an exception.

  2. When to use kotlin/java standard lib existing exceptions? Same as above, don't try to reinvent the wheel. Like,Use IllegalArgumentException instead of creating you own InvalidRequestException. Take a look here - https://programming.guide/java/list-of-java-exceptions.html

  3. Should you propagate spring Http exceptions to handler/controller layer? I'd suggest not propagating exceptions of any external framework to your controller. Rather, write your own exceptions, and use as much existing ones from Java.lang. Http exceptions should stay for where they are meant for, Request/Response layers.
  4. Is the scope of dependency exception above too large? Dependency Exception here is too broad, What if your application has to treat different Http codes in different ways. How will you handler manage that?
  5. Should 4xx,5xx error codes be converted to different custom exception types? (And also different handling of different codes in each series? ) Depends a lot on what the client wants. In your case as you have mentioned, you are handling them at orchestration layer and suppressing them. Do you see this implementation to change in future, and in how far? First step I'd suggest is to at least map 4xx and 5xx errors to different exceptions. Take a closer look, and see which ones you'd want to retry/recover from and derive another type from there.

Here's a few resourced I think you should look at -

https://itnext.io/graceful-error-handling-in-rest-driven-web-applications-d4209b4937aa

https://github.com/cloudendpoints/endpoints-java/blob/master/endpoints-framework/src/main/java/com/google/api/server/spi/ServiceException.java

REST API error return good practices

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM