6

I am using spring boot and write a global exception handler use AbstractErrorController. How could i get an exception object in controller?

@Controller
public class MyCustomErrorController extends AbstractErrorController {

    public MyCustomErrorController(ErrorAttributes errorAttributes) {
        super(errorAttributes);
    }

    @RequestMapping("/error")
    public void handleError(HttpServletRequest req, HttpServletResponse resp) {
        Exception e = ...; // how to get exception here
        log.error(e);
        displayError(req, resp, e);
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }
}
user1434702
  • 817
  • 1
  • 14
  • 33
  • I don't understand the logic here. Do you want to retrieve an error from an endpoint? Usually error handlers catch an exception and return an error for any controller that thrown that exception. – Otrebor Jan 21 '19 at 15:32

4 Answers4

4

You can get the exception from the HttpServletRequest as follows:

    @Controller
    public class MyCustomErrorController extends AbstractErrorController {
    
        @RequestMapping("/error")
        public void handleError(HttpServletRequest request) {
            Exception e = (Exception) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
            ...
        }
    }
trf
  • 1,279
  • 1
  • 13
  • 33
  • If this ErrorController pick up other error like resource not found from your database, or invalid endpoint /dsaklfja, the exception casted here is null – BabyishTank Apr 21 '22 at 22:07
0

An handler intercepts an Exception generated or re-thrown by a controller. It doesn't have an endpoint because it usually does it for all the controllers in your application. The Handler instructs the application server to return a specific error when a specific Exception is thrown.

Here is an example:

@ControllerAdvice // Specialization of @Component for classes that declare @ExceptionHandler, @InitBinder, or @ModelAttribute methods to be shared across multiple @Controller classes.
public class ResourceNotFoundExceptionHandler {

@ExceptionHandler(value = { ResourceNotFoundException.class })
public ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
    ApiError error = new ApiError(HttpStatus.NOT_FOUND,  ex.getLocalizedMessage(), ex);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

    ResponseEntity<Object> response = new ResponseEntity<>(error, headers, HttpStatus.NOT_FOUND);

    return response;
}
}

In this example ApiError is a data structure that reports the error to the UI. What this code does is intercepting the Exception "ResourceNotFoundException", create an appropriate error Data transfer object, set the response HttpStatus and headers and return the error.

you can find a different example here: https://github.com/otrebor/springbootseed-openshift/blob/master/src/main/java/com/company/example/springbootseed/core/errorhandling/handlers/

Otrebor
  • 416
  • 4
  • 12
  • 1
    But ControllerAdvice dosen't catch exception from filter. – user1434702 Jan 21 '19 at 16:06
  • did you have a look to https://github.com/otrebor/springbootseed-openshift/blob/master/src/main/java/com/company/example/springbootseed/core/errorhandling/handlers/RequestValidationErrorHandler.java ? – Otrebor Jan 21 '19 at 18:02
  • or https://stackoverflow.com/questions/34595605/how-to-manage-exceptions-thrown-in-filters-in-spring – Otrebor Jan 21 '19 at 18:06
  • You can get the endpoint point of which ever url failed by : String url = (String) request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI); – BabyishTank Apr 21 '22 at 22:04
0

Add Exception as an extra parameter to handleError()

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 21 '22 at 01:51
0

this is how it works in Spring Boot 3.1.0. But should work in previous versions as well:

import org.springframework.web.servlet.DispatcherServlet;

   @Controller
    public class MyCustomErrorController extends AbstractErrorController {
    
        @RequestMapping("/error")
        public void handleError(HttpServletRequest request) {
                   Exception e = (Exception) request.getAttribute(DispatcherServlet.EXCEPTION_ATTRIBUTE);

            ...
        }
    }