4

I am working on a microservice which does some calculation based on certain configurations stored in its own data store. The calculations apis are stored via REST APIs. The application is a spring boot application. Now there are mainly 3 layers in the application :

  1. REST Controller
  2. Service layer
  3. DAO layer - it used spring data.

I am planning to handle the logging and exception handling using below points:

  • Log each request that the service receives and response or at least the response if the status is not in 2xx series.

  • If there are any checked exception in either DAO layer or Service layer then log them and throw a custom exception derived from RuntimeException.

  • Have Several custom exception which should be thrown from Service layer mainly if we come across scenarios like invalid values, null values etc.

  • Have a try catch block in the REST Controller and log the exception i.e. message along with stacktrace and return the response accordingly.

So overall idea is to let the RuntimeExceptions propagate all the way to REST Controller where they should be logged and accordingly the response should be sent. Incase of checked exceptions log them in the same method and throw custom exceptions instead.

Please suggest what should be the correct or a good approach for logging exception in such applications.

user762421
  • 503
  • 1
  • 12
  • 24

2 Answers2

1

Write controller advice which will catch all the exceptions & logs the required contents. You may catch exceptions here. I implemented same what you asked here.

*/
/**
 * Uncaught exception handler
 * @param e - Exception
 */
@ExceptionHandler(Exception.class)
@ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public void handleError(Exception e,HttpServletRequest request, HttpServletResponse response){
    logger.error("Exception occured : {}",e);
        //logs request & response here
}

Also please check AbstractRequestLoggingFilter described here.

For all custom application specific exeptions create your own custom exception type & handle it with the help of @ExceptionHandler as specified in above code block.

abhi3232
  • 371
  • 1
  • 4
  • 15
0

Choose only one place to log the exceptions.

In your design, if an exception occurs in DAO, it will:

  • Get logged in DAO
  • Then trigger a runtime exception, which will be caught and logged in controller
  • Which should then return non-2xx response status via REST, which will trigger logging the response as per your first point

So you'll have either the same information in three places, or you will have the different bits of information regarding a single error scattered in two or three places across the log.

Choose a single place to log the errors, and make sure all relevant info is present at that place (i.e. set the underlying DAO exception as a cause of the runtime exception, and don't forget to log the runtime exception along with its cause).

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
  • So you are saying even if my e.g. AccountService (**not** the Controller) throws an "AccountLoginFailedException" (which derives from *RuntimeException*), I should be handling the exception in the RestController (or an attached ControllerAdvice)? – Igor Apr 06 '18 at 00:17
  • 1
    @Igor You should think about who can really handle the exception. Can the service handle it in a reasonable way? If so, then handle it. If not, then either wrap it in your own exception providing additional details that the service knows, or rethrow it to caller. – Jiri Tousek Apr 06 '18 at 07:05