For example 500 Internal Server could imply that the apache server
internally has some permission issue.
Not necessarily. Uncached errors in the server-side application will cause the java server to return a "controlled" error 500.
From the web client point of view, 500 means:
-Something went wrong (somewhere) on the server-side. We don't know what. Don't retry the request-
For everything, a 200 should be returned by the application code.
The catalogue of status code is wider, but 200 is basically the default code to say: Ok, everything went fine. I encourage you to look at the 2xx status code list to enrich server-client the communication.
For example, if any exception is thrown within a service method then a
500 is returned to the client. Is the HTTP response convention broken
by Spring?
That's ok. When application errors reach the application server, the server catches them and does return the only reasonable error for uncontrolled errors. 500.
In that case, because an exception might be thrown by application
code, shouldn't a 200 status code be returned?
That would be read in this way:
--the request successfully failed--
From the communication point of view, it doesn't seem to me effective. Usually, 5xx error codes mean: Try it much later, while 4xx codes mean: Try it again but, this time, do it well. Returning a 2xx code when the request didn't finish successfully. What are we communicating to the client?
We might argue that the text message will tell the user what to do, despite de https status code but, what happens if there's no user? How would you programme a machine-to-machine communication if every call ends "successfully"? Matching strings? Declaring custom status codes? Wouldn't that add unnecessary complexity?
Should the application code catch the error, return a 200 status code
and add a more business/application specific message.
Depends. If you want your application to be a good www citizen then no, you should not. It's good for web applications to make a proper usage of the architecture web. So, if you need to communicate an error (5xx, 4xx) alongside with a specific error message, then do It. Tell to the web client: the request has not been processed due to the following errors
Let's say the application database is having issues? Or is it OK to
return the 500 message?
It's ok, For this specific case, a 500 status code make sense. But, ultimately, depends on the requirements and your preferences. If you are concerned about how to manage the error handling with Spring web, it might interest the following links 1 or 2.
There is no need for writing try-catch
-Blocks all over the controller.
1) I would derive those Exceptions from a common ancestor
2) There is ExceptionHandler which catches exceptions of a certain kind and gives control to you, what to do next. In the exception, you could carry a message, which is returned, via the reponse's body.
Regarding to security concerns or leaky abstractions, I see no problem in providing in the response's body a reason like missing required field "password"
or Could not publish. Document is already published
.
Of ocurse you should avoid turning things inside out.
Best Answer
I would suggest that you avoid using a general exception in this case. General "something happened" type exceptions are fine for situations where there is nothing reasonable you can do about it.
In this case you seem to care about the various errors. The simplest way to do this is to create a single exception type that can hold the all the error data.
Then you have access to those fields wherever you want to catch it. If you know what all of these errors are going to be and have different actions you want to take given the various problems, you might want to have various exception types. That makes the exception handling easier because you declare which errors you want to catch in various places simply the
except
clause alone.You can even do both, a single exception type for most things and a specific type for issues that you need to single out and treat differently.