Java – Why is a Spring’s HttpClientErrorException an unchecked exception

exceptionsjavaspring

Oracle summarises the purpose of unchecked exceptions as:

The next question might be: "If it's so good to document a method's API, including the exceptions it can throw, why not specify runtime exceptions too?" Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small.

Ok, so unchecked exceptions are for any errors caused by programmer error. Sure.

Spring's documentation for the HttpClientErrorException (which extends RuntimeException) says the exception is for:

Exception thrown when an HTTP 4xx is received.

I can't see that this is a 'programmer error' exception.

In the scenario I'm testing, I'm making a query to a Spring RestTemplate, but the server it's querying may be down, and return a 404. This seems like a perfectly normal state of affairs, not a programming error.

Am I perhaps interacting with the Spring Framework incorrectly (ie. I should be detecting the 404 before using the RestTemplate?) or is there something else I'm not considering?

Best Answer

I think you are doing well.

See it from this point of view. Unchecked Exceptions - Controversy.

If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.

It's a handicap due to the above premise. Spring Rest Client doesn't expect to recover itself from a 404 so it delegates the decision of handling the error to upper layers.

It's your system's responsibility to decide what to do with 4xx or 5xx errors. The way to don't compromise the whole Spring Web and core architecture with useless try/catch/final blocks and refactor countless components adding the throw to signatures is typing exceptions asRuntimeExceptions.

In consequence, Spring user is involved in such eventuality. Spring delegate to us to take care and recover from these errors, or let them go (like they do) up to the next layers... And so on...

To your question

ie. Should I be detecting the 404 before using the RestTemplate?

It depends on what you need to do when the integration fails. I would suggest taking a look to fault tolerance patterns such as Circuit Breaker. This is a fairly known one, but there're more. Some times, the best you can do is let the exception go.

Finally, worth mention Spring's ErrorHandlers what let you handle errors in a more greaceful way. You can overwrite the method handleResponse too.