2

I'm using the @ExceptionHandler annotation on one of my controllers, but if I use any Exception type other than Exception.class, the page returns the message

The request sent by the client was syntactically incorrect.

Here's my controller:

@Controller @RequestMapping("/foobar") public class TodayInHistoryController { @Autowired(required = true) private TodayInHistoryService service; private static final String DATE_FMT = "yyyyMMdd"; /** * * @return */ @RequestMapping(method = RequestMethod.GET) public HistoryContent getTodayInHistory( @RequestParam(value = "date", required = false) Date date) { if (date != null) return service.getHistoryContent(date); return service.getHistoryContent(); } /** * Binds URL arguments to their correct object representation. * * @param binder */ @InitBinder public void initBinder(WebDataBinder binder) { // Date object binder SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FMT); binder.registerCustomEditor(Date.class, new CustomDateEditor( dateFormat, false)); } /** * * @return */ // If I change the value param of the annotation to Exception.class it works fine... @ExceptionHandler(NumberFormatException.class) public ModelAndView handleParseException(Exception ex) { // create and populate Map to hold error data Map<String, String> errorData = new HashMap<String, String>(); errorData.put("errorMessage","Formatting error occurred"); errorData.put("errorDetails", "None"); // create and return ModelAndView ModelAndView mv = new ModelAndView(); mv.addAllObjects(errorData); return mv; } } 

Here's my spring config (what's relevant)

@Configuration @Import(ServicesConfig.class) @ImportResource({ "classpath:applicationContext-security.xml", "classpath:dataSources.xml" }) @EnableWebMvc @ComponentScan(basePackages = "my.controller") public class WebConfig { @Bean public ViewResolver contentNegotiatingViewResolver() { ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setIgnoreAcceptHeader(true); resolver.setDefaultContentType(MediaType.APPLICATION_JSON); resolver.setFavorPathExtension(true); resolver.setOrder(1); // setup mediaTypes Map<String, String> mediaTypes = new HashMap<String, String>(); mediaTypes.put("json", "application/json"); mediaTypes.put("xml", "application/xml"); resolver.setMediaTypes(mediaTypes); // setup defaultViews List<View> defaultViews = new ArrayList<View>(); defaultViews.add(jsonView()); defaultViews.add(xmlView()); resolver.setDefaultViews(defaultViews); return resolver; } @Bean public View jsonView() { return new MappingJacksonJsonView(); } @Bean public View xmlView() { return new MarshallingView(new CastorMarshaller()); } } 
4
  • the message you're getting usually means that not all required parameters are present, but in your case the parameter is optional so I guess that there was an error converting the parameter other than NumberFormatException. Can you post your request url and CustomDateEditor? Commented Apr 6, 2012 at 15:05
  • I was actually passing a value to the URL that is not in the correct format on purpose in order to test Exception handling. If I do this with Exception.class as the value then it works as expected. An example incorrect URL would be /services/foobar?date=asdf . The service works fine with a correctly formatted date (i.e /services/foobar?date=20120401) Commented Apr 6, 2012 at 17:01
  • As far as the CustomDateEditor is concerned, is that needed here since I'm using an @InitBinder annotated method? Commented Apr 6, 2012 at 17:03
  • hah, forgot that CustomDateEditor is spring class ;) Commented Apr 6, 2012 at 17:37

1 Answer 1

2

The problem here is that spring tries to convert date string to Date and fails. When that happens TypeMismatchException (which wraps IllegalArgumentException, which in turn wraps ParseException) is thrown and you should handle that instead of NumberFormatException.

When you changed the exception class to Exception it got handled, as TypeMismatchException extends Exception.

A tip: if you're using any logging framework, try turning debug logging on for spring mvc classes, it can clear things up a lot.

For example put something like this in your lo4j.propeties:

log4j.logger.org.springframework.servlet=DEBUG 
Sign up to request clarification or add additional context in comments.

2 Comments

Your solution works, but I don't understand why the @ ExceptionHandler method is even called if the actual Exception is TypeMismatchException and not NumberFormatException. Shouldn't the ExceptionHandler be passed over in this case instead of giving the 'syntactically incorrect' error? I thought @ ExceptionHandler has the value attribute in order to only handle a subset of Exceptions.
It is passed over - the page and message you get is a default spring error page for TypeMismatchError (and many others), unless you have changed it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.