Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExceptionHandler in Spring

import org.springframework.beans.TypeMismatchException;
import javax.annotation.*;
import javax.servlet.http.*;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(value = "/aa")
public class BaseController {

    @RequestMapping(value = "/bb/{number}", method = RequestMethod.GET, produces = "plain/text")
    public void test(@PathVariable final double number, final HttpServletResponse response) throws IOException {
        throw new MyException("whatever");
    }

    @ResponseBody
    @ExceptionHandler(MyException.class)
    public MyError handleMyException(final MyException exception, final HttpServletResponse response) throws IOException {
        ...
    }

    @ResponseBody
    @ExceptionHandler(TypeMismatchException.class)
    public MyError handleTypeMismatchException(final TypeMismatchException exception, final HttpServletResponse response) throws IOException {
        ...
    }

    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    @ExceptionHandler
    public MyError handleException(final Exception exception) throws IOException {
        ...
    }
}

If I call http://example.com/aa/bb/20 the function handleMyException is executed, as expected.

However, if I call http://example.com/aa/bb/QQQ I would expect that the function handleTypeMismatchException is called, but instead, handleException is called, with exception of type TypeMismatchException.

a nasty workaround to make it would would be to test the type of exception inside handleException(), and call handleTypeMismatchException if the exception is of type TypeMismatchException.

but why does it now work? the exceptionhandler is chosen at runtime according to the type of exception? or it is chosen at compile time?

like image 946
David Portabella Avatar asked Apr 03 '13 09:04

David Portabella


1 Answers

Extract from official spring documentation:

You use the @ExceptionHandler method annotation within a controller to specify which method is invoked when an exception of a specific type is thrown during the execution of controller methods

Exception you're trying to catch is generated by spring itself(string-to-double convertion), before actual method execution. Catching it is not in spec of @ExceptionHandler. That does make sense - typically you wouldn't want to catch exceptions generated by framework itself.

like image 171
Petro Semeniuk Avatar answered Nov 09 '22 13:11

Petro Semeniuk