Skip to content
Advertisement

Spring Boot @ExceptionHandler hide Exception Name

I am using Spring Boot 1.3.X and have the following:

@RestController
@RequestMapping(path = "/foo")
public class FooController {

    @RequestMapping(method = RequestMethod.GET, params = { "fooBar" })
    public Collection<Entry> firstFoo() {
        //Do something
    }

    @RequestMapping(method = RequestMethod.GET, params = { "anotherFooBar" })
    public Collection<Entry> secondFoo() {
        //Do something other
    }

}

Which works as expected. When passing a wrong param, the following exception is raised:

{
    "error": "Bad Request", 
    "exception": "org.springframework.web.bind.UnsatisfiedServletRequestParameterException", 
    "message": "Parameter conditions "fooBar" OR "anotherFooBar" not met for actual request parameters: elementalFormulae={C11}", 
    "path": "/foo", 
    "status": 400, 
    "timestamp": 1455287433961
}

I then created an ExceptionHandler as seen below:

@ControllerAdvice
public class ExcptionController {

    @ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="Invalid parameter")
    @ExceptionHandler(UnsatisfiedServletRequestParameterException.class)
    private void foo() {
        //Log exception
    }
}

Which raises the following Exception:

{
    "error": "Bad Request", 
    "exception": "org.springframework.web.bind.UnsatisfiedServletRequestParameterException", 
    "message": "Invalid parameter", 
    "path": "/api/foo", 
    "status": 400, 
    "timestamp": 1455287904886
}

Is it possible to exclude the exception field from the JSON representation?

Advertisement

Answer

You can get the Error Attributes in your controller advice and then, only keep the Exposable Fields. Something like following:

@ControllerAdvice
public class ExcptionController {
    private static final List<String> EXPOSABLE_FIELDS = asList("timestamp", "status", "error", "message", "path");

    @Autowired private ErrorAttributes errorAttributes;

    @ExceptionHandler(UnsatisfiedServletRequestParameterException.class)
    private ResponseEntity foo(HttpServletRequest request) {
        Map<String, Object> errors = getErrorAttributes(request);
        errors.put("message", "Invalid parameter");

        return ResponseEntity.badRequest().body(errors);
    }

    private Map<String, Object> getErrorAttributes(HttpServletRequest request) {
        ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
        final boolean WITHOUT_STACK_TRACE = false;
        Map<String, Object> attributes = errorAttributes.getErrorAttributes(requestAttributes, WITHOUT_STACK_TRACE);

        // log exception before removing it
        attributes.keySet().removeIf(key -> !EXPOSABLE_FIELDS.contains(key));

        return attributes;
    }
}
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement