Reputation: 169
i have a SpringBoot controller, and i want to return the correct http code status for Exceptions. So, my question is: Which http statu code is better for Exception the "500" one or "409" one?
This is my code:
@PostMapping(value = {"", "/"})
public ResponseEntity<Response> create(@RequestBody StudioDto studioDto,
ServletRequest servletRequest, ServletResponse servletResponse) {
Response response = new Response();
try {
studioService.createStudio(studioDto);
response.setMessage("The studio was create");
response.setStatusCode(HttpServletResponse.SC_CREATED);
} catch (Exception e) {
response.setMessage("Op we have a little problem");
response.setErrorMessage(e.getMessage());
//Which one
//this one 5xx
response.setStatusCode(500);
//Or this one 4xx
response.setStatusCode(409);
}
return new ResponseEntity(response, response.getHttpStatus());
}
Upvotes: 13
Views: 105099
Reputation: 131496
5.XX codes mean error from the server side and 4.XXX codes mean error from the client side.
Here you catch any exception :
catch (Exception e) {
response.setMessage("Op we have a little problem");
response.setErrorMessage(e.getMessage());
//Which one
//this one 5xx
response.setStatusCode(500);
//Or this one 4xx
response.setStatusCode(409);
}
So it is clearly impossible to know if the problem came from the client request (bad parameter for example) or from a server error (inconsistency in DB or programmatic error for example).
To be able to set with precision 4.XXX or 5.XXX, your code could rely on some specific base exceptions as ClientErrorException
and ServerErrorException
.
Throw one or the other according to the error cause and you could then rely on them to set the correct status code :
try {
studioService.createStudio(studioDto);
response.setMessage("The studio was create");
response.setStatusCode(HttpServletResponse.SC_CREATED);
}
catch (ClientErrorException e) {
response.setStatusCode(409);
}
catch (ServerErrorException e) {
response.setStatusCode(500);
}
Another way could be to add the status code field in the exception base class.
You could so simply write :
try {
studioService.createStudio(studioDto);
response.setMessage("The studio was create");
response.setStatusCode(HttpServletResponse.SC_CREATED);
}
catch (MyRestException e) {
response.setStatusCode(e.getStatusCode());
}
These custom exceptions could be thrown directly from your code as you detect an error in the client request (4.XXX
).
In this way, you could consider all other exceptions as related to server processing (5.XXX
).
A Spring Exception Handler could easily perform this task.
Upvotes: 1
Reputation: 121849
Todd gave a great link. This is a better way of thinking about it:
1×× Informational
2×× Success
3×× Redirection
4×× Client Error * 400 Bad Request * 401 Unauthorized ... * 405 Method Not Allowed ...
5×× Server Error * 500 Internal Server Error * 501 Not Implemented * 502 Bad Gateway ...
In other words, each major number (200, 400, 500, etc.) is a CATEGORY. You can "refine" the error code by choosing a specific error within the "category".
To your original question:
If the Client request is "bad" (for example, illegal username/password), then return a 4xx.
If the Server somehow fails (for example, you can't read the database), then return a 5xx.
The "official" list of HTTP error codes is RFC 7231:
https://www.rfc-editor.org/rfc/rfc7231
Upvotes: 12
Reputation: 6574
This is not the recommended way to handle exceptions, you should use controller advice , check this link
The status code is defined by the specific scenario , 500 means internal server error which I would use for a problem which it's cause is not specified, for 409 it resembels conflict on the target resource
The request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request
you have many other status code which is suitable in different cases so I would say no specific status code is the right answer, you can check this link for more info
Upvotes: 5
Reputation: 31720
It depends on what message you are trying to convey. Think of the status code as guidance to the caller on what to do next. If it's an internal server error that the user is unlikely to be able to do anything about, a 500 error is appropriate.
The server encountered an unexpected condition that prevented it from fulfilling the request.
On the other hand, a 409 indicates a conflict that the user could conceptually resolve:
The request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request.
Most 400-level errors indicate that the user could, in theory, fix them and resubmit.
Personally, I would advise you to catch more exact exceptions and determine which status code each should return, because it really depends on your use case. As of now, you are catching Exception
, and that could be just about anything so it's hard to tell what kind of guidance you should give the caller.
Upvotes: 2