BadPractice6 - SpotBugsExtensionForSpringFrameWork/CS5098 GitHub Wiki

Bug Pattern Name: NON_SPECIFIC_WRAPPED_EXCEPTION_THROW Short Description: Use @ResponseStatusException over @ResponseStatus.

Description

There are many ways to deal with returning HTTP status responses. One of them is @ResponseStatus which is introduced in Spring 3.0 and one of others is @ResponseStatusException which was introduced in Spring 5.

We can use the @ResponseStatus annotation to set the status and reason in our HTTP response, BUT it creates tight coupling - all exceptions of type ActorNotFoundException (see example codes below) will generate the same error message and status code in the response.

ResponseStatusException usage has few benefits baeldung

  • Firstly, exceptions of the same type can be processed separately and different status codes can be set on the response, reducing tight coupling
  • Secondly, it avoids the creation of unnecessary additional exception classes
  • Finally, it provides more control over exception handling, as the exceptions can be created programmatically
// Bad Case 1: always return same error message 
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Actor Not Found")
public class ActorNotFoundException extends Exception {
    // ...
}

// Bad Case 2: always return same error message 
@RequestMapping(method = RequestMethod.POST, consumes = MediaType
                        .APPLICATION_FORM_URLENCODED_VALUE)
@ResponseStatus(HttpStatus.OK)
public void handleFormRequest (@RequestBody MultiValueMap<String, String> formParams) {
    System.out.println("form params received " + formParams);
}

// Good Case 1: can customise error message 
@GetMapping("/actor/{id}")
public String getActorName(@PathVariable("id") int id) {
    try {
        return actorService.getActor(id);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.NOT_FOUND, "Actor Not Found", ex);
    }
}

// Good Case 2: can customise error message 
@PutMapping("/actor/{id}/{name}")
public String updateActorName(
  @PathVariable("id") int id, 
  @PathVariable("name") String name) {
 
    try {
        return actorService.updateActor(id, name);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.BAD_REQUEST, "Provide correct Actor Id", ex);
    }
}

Reference List