There is lot of material & posts over the internet about ExceptionHandling in SpringBoot.
So here nothing special, even I am just summarizing the info given on :
Spring Boot Exception Handling | by Farzin Pashaee | May, 2022 | Medium
So for more details please check the above page or can search over the internet using the
below pointers.
As mentioned on above page there are 3 ways you can handle the exceptions in your
SpringBoot applications, well I am not sure if these are the only ones or there are others
hidden in Spring ecosystem. You can try to search the hidden ones & can comment below.
3 ways :-
1) @ControllerAdvice and @ExceptionHandler
2) Using HandlerExceptionResolver
3) Using ResponseStatusException
First the easiest one & not so good way to have in your enterprise applications-
Using ResponseStatusException
try {
result= businessService.doProcessing(<input>);
} catch (InvalidDataException e) {
e.printStackTrace();
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, e.getMessage(), e);
}
You see, you will be adding these try-ctach blocks in your controller layer & you are just type
casting from exception type to other, which you want to return to your client.
It is a good practise to convert the system level exception to Business understandable
exception with required message, rather throwing the whole stack trace to your client's face.
But this is also a kind of cross cutting concern, for which not your every developer writting the
service must be concerned & using the above simple way, we may be flooding over controller
layer with such try-catch blocks, which I don't think any one would like to see & review.
--------
So, lets see the other better way - Using HandlerExceptionResolver
For this we need to do some work like-
We need to implement HandlerExceptionResolver interface & provide the implementation for
its resolveException(), which has the return type as ModelAndView object & here you can
set the result in JSON format or if you need some HTML then use that.
Then add your implemented resolver to the resolvers list of WebMvcConfigurer, as shown
below-
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureHandlerExceptionResolvers(
List<HandlerExceptionResolver> resolvers) {
resolvers.add(0, new RestResponseStatusExceptionResolver());
}
}
So we see that concern of handling the exceptions is separated & your controller service will
not be cluttered with try-ctach blocks & if you want to have centralized way to handle the
system level exceptions & to convert them to business specific exceptions, you can do that
better now via this way.
But still few people think it requires quite extra work to make it work.
--------
So lets see the best way available currently - @ControllerAdvice and @ExceptionHandler
This way you can create a separate controller with @ControllerAdvice which will be
handling only exceptions in your application.
For different exceptions you can create different methods & use @ExceptionHandler with
the exception name on each method. For more details check the above given page or check
over the internet. Below is one example taken from above URL-
@ControllerAdvice
public class ExceptionControllerAdvice {
@ResponseBody
@ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
@ExceptionHandler(value= { ServiceDownTimeException.class })
protected ServiceDownTimeException handleConflict(ServiceDownTimeException exception, HttpServletResponse response) {
return exception;
}
}
Note: No way given here is good or bad, though I am saying one as best way, but it all
depends on your requirements, i.e. if you are required handle many exceptions & want to
centralize that, then above one should be the best way. But only a few exceptions you will be
handling then one can use simple way also.
Purpose of this post was to give a glimpse of 3 ways at one place but you can create your
own interceptor/filters to handle the exceptions.
So here nothing special, even I am just summarizing the info given on :
Spring Boot Exception Handling | by Farzin Pashaee | May, 2022 | Medium
So for more details please check the above page or can search over the internet using the
below pointers.
As mentioned on above page there are 3 ways you can handle the exceptions in your
SpringBoot applications, well I am not sure if these are the only ones or there are others
hidden in Spring ecosystem. You can try to search the hidden ones & can comment below.
3 ways :-
1) @ControllerAdvice and @ExceptionHandler
2) Using HandlerExceptionResolver
3) Using ResponseStatusException
First the easiest one & not so good way to have in your enterprise applications-
Using ResponseStatusException
try {
result= businessService.doProcessing(<input>);
} catch (InvalidDataException e) {
e.printStackTrace();
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, e.getMessage(), e);
}
You see, you will be adding these try-ctach blocks in your controller layer & you are just type
casting from exception type to other, which you want to return to your client.
It is a good practise to convert the system level exception to Business understandable
exception with required message, rather throwing the whole stack trace to your client's face.
But this is also a kind of cross cutting concern, for which not your every developer writting the
service must be concerned & using the above simple way, we may be flooding over controller
layer with such try-catch blocks, which I don't think any one would like to see & review.
--------
So, lets see the other better way - Using HandlerExceptionResolver
For this we need to do some work like-
We need to implement HandlerExceptionResolver interface & provide the implementation for
its resolveException(), which has the return type as ModelAndView object & here you can
set the result in JSON format or if you need some HTML then use that.
Then add your implemented resolver to the resolvers list of WebMvcConfigurer, as shown
below-
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureHandlerExceptionResolvers(
List<HandlerExceptionResolver> resolvers) {
resolvers.add(0, new RestResponseStatusExceptionResolver());
}
}
So we see that concern of handling the exceptions is separated & your controller service will
not be cluttered with try-ctach blocks & if you want to have centralized way to handle the
system level exceptions & to convert them to business specific exceptions, you can do that
better now via this way.
But still few people think it requires quite extra work to make it work.
--------
So lets see the best way available currently - @ControllerAdvice and @ExceptionHandler
This way you can create a separate controller with @ControllerAdvice which will be
handling only exceptions in your application.
For different exceptions you can create different methods & use @ExceptionHandler with
the exception name on each method. For more details check the above given page or check
over the internet. Below is one example taken from above URL-
@ControllerAdvice
public class ExceptionControllerAdvice {
@ResponseBody
@ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
@ExceptionHandler(value= { ServiceDownTimeException.class })
protected ServiceDownTimeException handleConflict(ServiceDownTimeException exception, HttpServletResponse response) {
return exception;
}
}
Note: No way given here is good or bad, though I am saying one as best way, but it all
depends on your requirements, i.e. if you are required handle many exceptions & want to
centralize that, then above one should be the best way. But only a few exceptions you will be
handling then one can use simple way also.
Purpose of this post was to give a glimpse of 3 ways at one place but you can create your
own interceptor/filters to handle the exceptions.