Search code examples
javaspring-bootrestexceptioncontroller-advice

How to catch NotFoundException with ControllerAdvice in Spring Boot?


I'm working at a Spring Boot project and I want to handle the exceptions for the REST API using @ControllerAdvice. And I want to handle the case when the endpoint is not spelled correctly. For example the endpoint should be http://localhost:8080/website and the client app makes a mistake and call the endpoint http://localhost:8080/websit and right now I get that response in the browser:

Here is the response that I get now:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sun Nov 19 15:31:33 EET 2023
There was an unexpected error (type=Not Found, status=404).

I want to know if I can handle it with @ControllerAdvice and I don't know what kind of NotFoundException to catch in the ControllerAdvice class.

ControllerAdvice class:

import com.ds.ecommerce.exception.PriceNotFoundException;
import javassist.NotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.xml.bind.ValidationException;

@Slf4j
@ControllerAdvice
public class PricesGlobalExceptionHandler {
    @ResponseBody
    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorDTO handleException(Exception exception) {
        log.error(exception.getMessage(), exception);
        return ErrorDTO.builder()
                .code(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase())
                .message("Unexpected error!")
                .build();
    }

    @ResponseBody
    @ExceptionHandler(value = {ValidationException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorDTO handleException(ValidationException validationException) {
        String exceptionMessage = validationException.getMessage();
        log.error(exceptionMessage, validationException);
        return ErrorDTO.builder()
                .code(HttpStatus.BAD_REQUEST.getReasonPhrase())
                .message(exceptionMessage)
                .build();
    }

    @ResponseBody
    @ExceptionHandler(value = {PriceNotFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorDTO handleException(PriceNotFoundException priceNotFoundException) {
        String exceptionMessage = priceNotFoundException.getMessage();
        log.error(exceptionMessage, priceNotFoundException);
        return ErrorDTO.builder()
                .code(HttpStatus.NOT_FOUND.getReasonPhrase())
                .message(exceptionMessage)
                .build();
    }

    @ResponseBody
    @ExceptionHandler(value = {NotFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorDTO handleException(NotFoundException notFoundException) {
        String exceptionMessage = notFoundException.getMessage();
        log.error(exceptionMessage, notFoundException);
        return ErrorDTO.builder()
                .code(HttpStatus.NOT_FOUND.getReasonPhrase())
                .message(exceptionMessage)
                .build();
    }
}

I think I'm not using the correct NotFoundException class to catch it. Thank you!


Solution

  • ControllerAdvice handles only exceptions that originate from within some end-point method and are not cought. If your URL is misspelled, than obviously your code did not yet enter any of the end-points and thus the exception will not be handled by ControllerAdvice.