@Test public void handleMissingPathVariable() throws NoSuchMethodException { Method method = getClass().getMethod("handle", String.class); MethodParameter parameter = new MethodParameter(method, 0); MissingPathVariableException ex = new MissingPathVariableException("foo", parameter); ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex); assertNotNull("No ModelAndView returned", mav); assertTrue("No Empty ModelAndView returned", mav.isEmpty()); assertEquals("Invalid status code", 500, response.getStatus()); assertEquals("Missing URI template variable 'foo' for method parameter of type String", response.getErrorMessage()); }
@Test public void missingPathVariable() throws NoSuchMethodException { Method method = getClass().getDeclaredMethod("handle", String.class); MethodParameter parameter = new MethodParameter(method, 0); Exception ex = new MissingPathVariableException("param", parameter); testException(ex); }
@ExceptionHandler({UnrecognizedPropertyException.class, MissingPathVariableException.class}) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public JSONError unrecognizedProperty(Exception e) { log.warn(e.getMessage(), e); return JSONError.badRequest(); }
@Override protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try { if (ex instanceof NoSuchRequestHandlingMethodException) { return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, request, response, handler); } else if (ex instanceof HttpRequestMethodNotSupportedException) { return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request, response, handler); } else if (ex instanceof HttpMediaTypeNotSupportedException) { return handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException) ex, request, response, handler); } else if (ex instanceof HttpMediaTypeNotAcceptableException) { return handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException) ex, request, response, handler); } else if (ex instanceof MissingPathVariableException) { return handleMissingPathVariable((MissingPathVariableException) ex, request, response, handler); } else if (ex instanceof MissingServletRequestParameterException) { return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, request, response, handler); } else if (ex instanceof ServletRequestBindingException) { return handleServletRequestBindingException((ServletRequestBindingException) ex, request, response, handler); } else if (ex instanceof ConversionNotSupportedException) { return handleConversionNotSupported((ConversionNotSupportedException) ex, request, response, handler); } else if (ex instanceof TypeMismatchException) { return handleTypeMismatch((TypeMismatchException) ex, request, response, handler); } else if (ex instanceof HttpMessageNotReadableException) { return handleHttpMessageNotReadable((HttpMessageNotReadableException) ex, request, response, handler); } else if (ex instanceof HttpMessageNotWritableException) { return handleHttpMessageNotWritable((HttpMessageNotWritableException) ex, request, response, handler); } else if (ex instanceof MethodArgumentNotValidException) { return handleMethodArgumentNotValidException((MethodArgumentNotValidException) ex, request, response, handler); } else if (ex instanceof MissingServletRequestPartException) { return handleMissingServletRequestPartException((MissingServletRequestPartException) ex, request, response, handler); } else if (ex instanceof BindException) { return handleBindException((BindException) ex, request, response, handler); } else if (ex instanceof NoHandlerFoundException) { return handleNoHandlerFoundException((NoHandlerFoundException) ex, request, response, handler); } } catch (Exception handlerException) { if (logger.isWarnEnabled()) { logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException); } } return null; }
@Override protected void handleMissingValue(String name, MethodParameter parameter) throws ServletRequestBindingException { throw new MissingPathVariableException(name, parameter); }
@Test(expected = MissingPathVariableException.class) public void handleMissingValue() throws Exception { resolver.resolveArgument(paramNamedString, mavContainer, webRequest, null); fail("Unresolved path variable should lead to exception."); }
@ExceptionHandler({ HttpRequestMethodNotSupportedException.class, HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class, MissingPathVariableException.class, MissingServletRequestParameterException.class, ServletRequestBindingException.class, ConversionNotSupportedException.class, TypeMismatchException.class, HttpMessageNotReadableException.class, HttpMessageNotWritableException.class, MethodArgumentNotValidException.class, MissingServletRequestPartException.class, BindException.class, AsyncRequestTimeoutException.class }) public final Object handleSpringException(Exception ex, HandlerMethod handlerMethod) { HttpStatus status; if (ex instanceof HttpRequestMethodNotSupportedException) { status = HttpStatus.METHOD_NOT_ALLOWED; return handleException(ex, handlerMethod, status, null); } else if (ex instanceof HttpMediaTypeNotSupportedException) { status = HttpStatus.UNSUPPORTED_MEDIA_TYPE; return handleException(ex, handlerMethod, status, null); } else if (ex instanceof HttpMediaTypeNotAcceptableException) { status = HttpStatus.NOT_ACCEPTABLE; return handleException(ex, handlerMethod, status, null); } else if (ex instanceof MissingPathVariableException || ex instanceof ConversionNotSupportedException || ex instanceof HttpMessageNotWritableException) { status = HttpStatus.INTERNAL_SERVER_ERROR; return handleException(ex, handlerMethod, status, null); } else if (ex instanceof MissingServletRequestParameterException || ex instanceof ServletRequestBindingException || ex instanceof TypeMismatchException || ex instanceof HttpMessageNotReadableException || ex instanceof MethodArgumentNotValidException || ex instanceof MissingServletRequestPartException || ex instanceof BindException) { status = HttpStatus.BAD_REQUEST; return handleException(ex, handlerMethod, status, null); } else if (ex instanceof AsyncRequestTimeoutException) { status = HttpStatus.SERVICE_UNAVAILABLE; return handleException(ex, handlerMethod, status, null); } else { if (LOG.isWarnEnabled()) { LOG.warn("Unknown exception type: " + ex.getClass().getName()); } status = HttpStatus.INTERNAL_SERVER_ERROR; return handleException(ex, handlerMethod, status, null); } }
/** * Handle the case when a declared path variable does not match any extracted URI variable. * <p>The default implementation sends an HTTP 500 error, and returns an empty {@code ModelAndView}. * Alternatively, a fallback view could be chosen, or the MissingPathVariableException * could be rethrown as-is. * @param ex the MissingPathVariableException to be handled * @param request current HTTP request * @param response current HTTP response * @param handler the executed handler * @return an empty ModelAndView indicating the exception was handled * @throws IOException potentially thrown from response.sendError() * @since 4.2 */ protected ModelAndView handleMissingPathVariable(MissingPathVariableException ex, HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex.getMessage()); return new ModelAndView(); }
/** * Customize the response for MissingPathVariableException. * <p>This method delegates to {@link #handleExceptionInternal}. * @param ex the exception * @param headers the headers to be written to the response * @param status the selected response status * @param request the current request * @return a {@code ResponseEntity} instance * @since 4.2 */ protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { return handleExceptionInternal(ex, null, headers, status, request); }