0

I have created a custom REST Controller Exception Handler for my spring boot application ...

@ControllerAdvice(annotations = RestController.class)
public class RestControllerExceptionHandler {    
  @ExceptionHandler(TechnicalException.class)
  public ResponseEntity handleTechnicalException(TechnicalException e) {    
    return new ResponseEntity<>(
        new RestErrorMessageModel(e.getErrorCode(), e.getMessage()), BAD_REQUEST
    );
  }

  @ExceptionHandler(BusinessException.class)
  public ResponseEntity handleBusinessException(BusinessException e) {    
    return new ResponseEntity<>(
        new RestErrorMessageModel(e.getErrorCode(), e.getMessage()), BAD_REQUEST
    );
  }

  @ExceptionHandler(ValidationException.class)
  public ResponseEntity handleValidationException(ValidationException e) {    
    return new ResponseEntity<>(
        new RestErrorMessageModel(e.getErrorCode(), e.getDetails()), BAD_REQUEST
    );
  }
}

... where I handle validation, business (exceptions that caused because of violation of business rules) and technical (database related, invalid request parameters, etc.) exceptions.

The exception classes have two parameters: errorCode (unique enum) and message (exception details).

As you can see from the example, for all cases I return BAD_REQUEST (400) status, which is not the best practice.

I would like to know the best way to handle HTTP statuses based on the exception category, for example: for validation errors returning BAD_REQUEST (400) status is "okay".

... or is there any way which lets spring-boot "decides" which status code to send?

1
  • More or less the rule of thumb is this: 4xx = client error ==> tells the client of your web service that they have made something wrong. 5xx = server error ==> tells the client that you (the web service server) have some issues. 4xx = you forgot to give me flowers, 5xx = I have a headache :) Commented Dec 2, 2019 at 13:51

3 Answers 3

1

From java & spring side, use @ControllerAdvice and @ExceptionHandler is a best practice.

From values of error codes, there is no standard. But you could:

1. Follow the old https code status standard

  • 1xx informational response – the request was received, continuing process
  • 2xx successful – the request was successfully received, understood and accepted
  • 3xx redirection – further action needs to be taken in order to complete the request
  • 4xx client error – the request contains bad syntax or cannot be fulfilled
  • 5xx server error – the server failed to fulfill an apparently valid request

2. Copy from World Class Companies

https://developer.paypal.com/docs/api/reference/api-responses/#http-status-codes

3. Implement your own codes without collide the http old standards

https://developer.paypal.com/docs/classic/api/errors/#10000-to-10099

Sign up to request clarification or add additional context in comments.

Comments

0

Since the type of errors may vary in application and it is not possible to have common HTTP status for all these errors I solved it by creating custom mapper which maps error codes to HTTP statuses.

Since error codes are unique and each of them used for a special exception handling, I can map error codes to Http statuses.

2 Comments

What do you mean by custom mapper?
@HarryCoder the custom method which returns HttpStatus based on errorCode: if (errorCode in (....)) then return HttpStatus.NOT_FOUND else if (errorCode in (....)) then return HttpStatus.CONFLICT etc.
0

You can always setup HttpStatus property in Exception and in Handler just get value of status and configure it in ResponseEntity. Basically HttpStatus depends on context of executed task. Your Technical or Business Exception can return 400, 404, 409 etc. I think good solution is define HttpStatus during throwing suitable exception. If you dont want to define many Exception per HttpStatus you can use org.springframework.web.server.ResponseStatusException.

1 Comment

It would be great of you could add a code snippet in addition to your explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.