Jonathan Hagen
Jonathan Hagen

Reputation: 732

ControllerAdvice, ExceptionHandler and try catch block in RestController

I have generic question about @ControllerAdvice and @ExceptionHandler. I have a rest controller annotated @RestController that has 2 apis. If argument validation fails, it throws MethodArgumentNotValidException. I created ExceptionHandler to handle this:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public ResponseEntity<String> handleException(MethodArgumentNotValidException e) throws Exception {
        return new ResponseEntity<>(e.getBindingResult().getGlobalError().getDefaultMessage(), HttpStatus.BAD_REQUEST);
    }
}

If I want to log something when this exception happens, can I just add line of code before return statement like:

LOG.info("something happened");

Will it log it and then return BAD_REQUEST back to the caller?

Upvotes: 0

Views: 1956

Answers (1)

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85781

If I want to log something when this exception happens, can I just add line of code before return statement like:

LOG.info("something happened");

Will it log it and then return BAD_REQUEST back to the caller?

Yes. That's the purpose of using @ExceptionHandlers. They help to reduce the code to handle exceptions across several rest endpoints defined in your project. This also serves as the single point to log exceptions, thus avoiding this anti pattern:

//BAD
class SomeService {
    public SomeEntity someMethod() {
        try {
            /* stuff... */
        } catch (Exception e) {
            //No need to log the exception here
            log.error("An exception happened", e);
            throw e;
        }
    }
}

Still, you can have some benefits like wrapping the exceptions and rethrow them:

//GOOD
class SomeService {
    public SomeEntity someMethod(String param) {
        try {
            /* stuff... */
        } catch (Exception e) {
            //You may use this to perform other logic like setting specific message or wrap your exception
            log.error("Unexpected behaviour with param {}", param);
            throw new MyCustomException("Some message", e);
        }
    }
}

You can think of the @ExceptionHandler as a giant catch block for all your rest endpoints and a specific type of exception.

Besides, your GlobalExceptionHandler class becomes the component with logic associated to handle every exception thrown in backend and handles how to report that to client side.

Upvotes: 2

Related Questions