Spring Exception handler - Handling multiple exceptions - spring

Below is my ExceptionHandler method to handle different exceptions that can be thrown from service class.
#ExceptionHandler({ExceptionA.class, ExceptionB.class, ExceptionC.class})
#ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
#ResponseBody
public void handle(ExceptionA e) {
log.error("Exception occurred: {} {}", e.getMessage(), e);
}
When ExceptionA is thrown, everything works as expected. But when ExceptionB is thrown, it gives the error No suitable resolver for argument 0 of type 'ExceptionA'. I guess its because the method argument for handle method is Exception A (still I would expect the error message should say No resolver for Exception B).
What should be the method argument for handle method so that it can handle any of the 3 exceptions?
Note: All Exceptions are created by extending from RuntimeException.

You need a common base class as parameter type, e.g RuntimeException:
#ExceptionHandler({ExceptionA.class, ExceptionB.class, ExceptionC.class})
#ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
#ResponseBody
public void handle(RuntimeException e) {
log.error(e.getMessage(), e);
}

Make your own base class extending RuntimeException
public class HandledRuntimeException extends RuntimeException{
}
and extend this class from your exception class like,
public class ExceptionA extends HandledRuntimeException{
}
and finally, in your handle method, you can change as below
#ExceptionHandler({HandledRuntimeException.class})
#ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
#ResponseBody
public void handle(HandledRuntimeException e) {
log.error("Exception occurred: {} {}", e.getMessage(), e);
}

Related

preventing or handle jax-rs bean validation exception

is there a way to handle jax-rs validation exception, I mean to not the throwing exception, just sysout my string.
I use #Valid annotation in this way
public function name (#Valid DtoClassName dtoVariableName);
using resteasy 2 and wildfly 19.
I use mapper as previous answers here, but nothing work, it's throw the exception then call the mapper.
#Provider
public class ValidationExceptionMapper implements ExceptionMapper<javax.validation.ConstraintViolationException> {
public ValidationExceptionMapper() {
System.out.println("ValidationExceptionMapper");
// TODO Auto-generated constructor stub
}
#Override
public Response toResponse(ConstraintViolationException exception) {
// TODO Auto-generated method stub
return Response.status(Status.BAD_REQUEST).entity("HELLLO ERROR").build();
}
}

How to catch all the exceptions in Spring boot 2 webflux with #ControllerAdvice

My application is made by Spring Boot 2 webflux and thymeleaf, I want to catch all the exception and render the error to a customized error page.
I use #ControllerAdvice and #ExceptionHandler to catch exceptions and handle errors in a central place, I can only handle all the exceptions which are thrown in my controller, but I cannot catch
those mapping errors (content negotiation and HTTP mapping errors) such as UnsupportedMediaTypeStatusException.
I searched and find this is a known issue (https://github.com/spring-projects/sprienter code hereng-framework/issues/21097#issuecomment-453468295).
If I use WebMvc, there is no this kind of problem, all exceptions can be caught. My question is how to catch all the exceptions and show my own error page in webflux.
Here is the brief code:
#ControllerAdvice
#Slf4j
public class DefaultExceptionHandlers {
// works OK for my own thrown exception
#ResponseStatus(HttpStatus.FORBIDDEN)
#ExceptionHandler(value = CustomException1.class)
public Mono<String> handleCustom1Exceptions(CustomException1 e) {
return Mono.just("error1");
}
// works OK for my own thrown exception
#ResponseStatus(HttpStatus.BAD_REQUEST)
#ExceptionHandler(value = CustomException2.class)
public Mono<String> handleCustom2Exceptions(CustomException2 e) {
return Mono.just("error2);
}
// This exception handler is not called at all for the exceptions which are thrown by spring framework
#ResponseStatus(HttpStatus.FORBIDDEN)
#ExceptionHandler(value = Exception.class)
public Mono<String> handleAllExceptions(Exception e) {
return Mono.just("error3);
}
}

Generic exception handler prevents specific exception being handled

I have a spring boot application and there I handle exceptions. I have two exception handler methods for now:
#ControllerAdvice
#RestController
public class MyExceptionHandler {
#ExceptionHandler(Exception.class)
#ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public final BaseResponse<GenericException> handleGenericExceptions(Exception ex, HttpServletRequest request) {
....
return response;
}
#ExceptionHandler(MyCustomException.class)
#ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public final BaseResponse<MyCustomException> handleMyCustomException(MyCustomException ex, HttpServletRequest request) {
....
return response;
}
}
At some point, I throw a MyCustomException exception, but when I debug I see that it is handled by handleGenericExceptions method. If I delete handleGenericExceptions method, then it is handled by handleMyCustomException message.
I want MyCustomException to be handled by handleMyCustomException method, and all other exceptions by handleGenericExceptions method. MyCustomException class extends Throwable. What is wrong here?
Thanks.
I found the solution, but I do not now why this is the case.
MyCustomException class was extending Throwable, I changed it to extend RunTimeException instead. Now it is working as expected.
I don't have 50 repuatations,so I answered here, hope it make sense.
Throwable class have two important subclass ,Error and Exception . your MyCustomException extend Throwable. In spring , if your code throws which extends Throwable , Spring defaultly will decorate it as an IllegalStateException! I see this in spring4.3 source code , if you want to prove this , you add #ExceptionHandler({IllegalStateException}) and make your MyCustomException unmodified , this method will catch it!
Above evidence is in org.springframework.web.method.support.InvocableHandlerMethod#doInvoke.
By the way , we usually throw Exception by extends RuntimeException , why you want to throw an Throwable .

#ExceptionHandler(Exception.class) not able to catch HibernateOptimisticLockingFailureException

[WARNING] Could not send response error 500: org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException
I'm writing exception handlers using #ControllerAdvice & #ExceptionHandler in spring. I have a generic exception handler as below:
#ControllerAdvice
public class GlobalExceptionHandler {
final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
//other ExceptionHandlers to catch specific exceptions
#ExceptionHandler(Exception.class)
#ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
#ResponseBody
public ErrorMessage handleException(Exception ex) {
//other code
logger.error("Exception in API", ex);
//other code
}
}
Why i'm not able to catch exception in 'handleException'?, why spring say it's a warning not as an error?
Update:
In DAO layer because of wrong-input for an operation, hibernate throws HibernateOptimisticLockingFailureException. Yet, why my GlobalExceptionHandler(Global Exception Class) is not able to catch this ?

CXF - custom exception is not caught by CXF

I am developing a SOAP web service with CXF 2.3.3. I want to throw a custom exception when user has submitted wrong data. My exception class looks like this.
#WebFault(name="InvalidUserDataException", targetNamespace="http://foo.bar.com/")
#XmlAccessorType(XmlAccessType.FIELD)
public class InvalidUserDataException extends RuntimeException {
public InvalidUserDataException(){
super();
}
String validationErrors;
}
In my method Impl class I purposely throw this exception to see whether SoapFault exception is returned by CXF to client, but whatever I do to any of these classes results in same error: createNewUser has thrown exception, unwinding now.
Note that WSUserRegistration interface also declares itself that createNewUser method throws InvalidUserDataException.
public class WSUserRegistrationImpl implements WSUserRegistration {
#Autowired
IWSUserValidationProxy validationProxyImpl;
#Override
public int createNewUser(RegistrationInputProperty registrationInfo) throws InvalidUserDataException {
if (true) {
throw new InvalidUserDataException();
}
return 1;
}
}
My goal is to catch this exception from a SOAPFaultOutInterceptor and return a customized faultDetail.
How do I make CXF catch this error and return a SOAPFault object? Any ideas?
this would help you.
http://willemjiang.blogspot.com/2011/01/how-to-map-soap-fault-message-with.html

Resources