Exception for REST services for invalid input requests - java

I am currently developing REST services and throwing BadRequestException for all of the following,
1. Path parameter is invalid
2. Query parameter is invalid
4. Input request object has missing attributes
Is there any specific exceptions for each case like InvalidParameterException or so..? Is there any documentation available to learn which exceptions should be thrown on what situations?

I think it's a personal decision and the answer will depend on your needs to have more detailed expceptions or not.
There are two ways to handle errors with JAX-RS:
Throwing a WebApplicationException
That's the approach you are using, which allows you to map exceptions that extend WebApplicationException to HTTP error responses.
I think throwing a BadRequestException is just fine for all the situations mentioned in your question. Just remember adding a detailed message explaining what was wrong.
If you need a more specific exception, you could consider extending the BadRequestException or maybe the ClientErrorException. The new exceptios could encapsulate the message which explains what the problem with the request. It's up to your needs.
For more details on the exceptions provided by the JAX-RS API, have a look at the javax.ws.rs package documentation. If they do not fit your needs, just extend them and create your specific exceptions.
Using an ExceptionMapper
In other cases it may not be appropriate to throw instances of WebApplicationException, or classes that extend WebApplicationException, and instead it may be preferable to map an existing exception to a response. For such cases it is possible to use a custom exception mapping provider.
Consider, for example, you decide to throw an IllegalArgumentException whenever you received an inapropriate value for your query or path parameters. You can create an ExceptionMapper to map the IllegalArgumentException to a response with the 400 status code:
#Provider
public class IllegalArgumentExceptionMapper
implements ExceptionMapper<IllegalArgumentException> {
#Override
public Response toResponse(IllegalArgumentException exception) {
return Response.status(400).entity(exception.getMessage())
.type("text/plain").build();
}
}
For more details, have a look at the Jersey documentation.

All 3 errors sound like client errors, as the client fails to abide by the contract - so I would return a HTTP 400 Bad Request - perhaps with an explanation in the body of the response.

I believe usually you would create separate cases depending on how you would like to handle these errors. For example, you will have 3 different exceptions to represent your errors.
Most frameworks then allow you to install ExceptionMappers. These map your exceptions to an HTTP response code. These are documented and you should follow them:
For example: http://www.restapitutorial.com/httpstatuscodes.html
In your case for example, I would throw IllegalArgumentExceptions for all those 3 cases and install a mapper, mapping this to a 400 response code with potentially some info.
This can be for example important since the client consuming your service will not receive your exceptions anyway, but rather analyse the response code of the request. With a 400, a user will then know that the request was invalid and won't be retried. You can have similar cases for all sorts.
To read about exception mappers, for example with the help of jersey:
https://jersey.java.net/documentation/latest/representations.html
So to your question:
No, I don't believe there is any best-practise on what Exceptions are thrown from your application. Usually REST frameworks don't have specific exception mappers other than a catch-all mapper that will return a 500 (Internal Server Error)
There is however documentation for REST and the HTTP with regards to which responses should be returned for specific use cases. You should try and design your REST endpoint to conform to those standards for maximum reusability and understandability.
I hope that helps,
Artur

Related

What to return to from a REST API when updates fail

I am writing a web application using Spring Boot that frequently updates data on the back end and returns the updated object to reflect the update on the front end.
The question I have is what to return from my methods if the update should fail for some reason.
I am currently returning the object as it was received should it fail but as it stands the state on the front end would not reflect the failure on the back end in the case that it occurs.
I want to return the object to update the state but doing so prevents me from returning a String or HttpStatus indicating a problem doesn't it? Returning the old object doesn't seem a good solution either.
You can throw an exception in this case of failure from your REST controller.
To handle this exception, Spring provides ResponseEntityExceptionHandler callback class with the help of which you can handle the thrown exception and set different headers in the response entity.
So on client-side, you can recognise that some failure is occurred on server side.
You can set HttpStatus as HttpStatus.INTERNAL_SERVER_ERROR and add more details in the body.
The question I have is what to return from my methods if the update should fail for some reason.
You first need to determine whether the error was caused by the client or by the server, then you can determine the most suitable status code to be returned, either in the 4xx or in the 5xx range. See this answer which may give you some insights.
Instead of returning the request request back in the response, you should return a payload that describes what the problem was. Consider, for example, the payload defined in the RFC 7807 along with the application/problem+json media type.
Finally, this answer may give you insights on how to map an exception to a HTTP status code in Spring:
You can map exceptions to responses by annotating an exception class with #ResponseStatus.
It also gives you the possibility to implement a HandlerExceptionResolver or extend one of the existing implementations, such as the AbstractHandlerExceptionResolver.
Another approach would be using a ResponseEntityExceptionHandler annotated with #ControllerAdvice and define the handled exceptions by annotating the implemented method with #ExceptionHandler.

Production level Exception handling in spring boot

I have a scenario :
UI<--->Spring boot micro-service REST API<--->server
Now, there is a situation in which I want to handle custom exceptions(which I am aware how to do) in order to return specific Http Status and message back to UI when server responds in certain manner for e.g. 500 should return "Please return after a while" insteal of "internal server error". The maven project for our micro-service is divided into 3 layers (sub maven projects) i.e. Business, Web and Domain. Where web contains controller class, Business contains Service class and Domain contains #Entity, #Components etc.
I want to know in order to handle the above mentioned exception let say HTTP Status 500, should be done at business layer? or at web layer i.e. controller level. What would be the best possible solution? (I am aware of ResponseEntity and how it can provide a customized response to UI).
I personally believe that if I include custom exception class at Business Level and return that in Controller class using response entity after checking the response status would do the trick. But officials feel that it should be done at service level? I am not able to understand why(it makes the process more complex)? can anyone suggest which solution is best?
Officials are right, it should be in Service Layer. I would say best practice would be to use #ExceptionHandler. As the downside to handling the exception in the controller method is that it makes the code less readable and might be repeated across many controller methods.
I would recommend having a base class for your controllers with the #ExceptionHandler defined. This way it can be used for many different controllers, without any code duplication. This would be more readable than the exception resolver approach, but could be used in conjunction
This is clearly explained here
If you want to handle error in a global level, you can use #ControllerAdvice which is very easy when comes to the handling custom exceptions as well as runtime exceptions.
you can throw exceptions from business layer to web controllers and define a #ControllerAdvice class to catch those errors and provide responses with correct response status.
For Ex:-
#ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
#ExceptionHandler(value = { IllegalArgumentException.class, IllegalStateException.class })
protected ResponseEntity<Object> handleConflict(RuntimeException ex, WebRequest request) {
String bodyOfResponse = "This should be application specific";
return handleExceptionInternal(ex, bodyOfResponse,
new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}
and throw those Exception classes from the controller classes also, you dont need to catch exception from the controllers.
Hope this helps to you...
Above code snipplet i took from here
Error response is usually generated by #ExceptionHandler matching your exception type and maybe registered with #ConrtrollerAdvice as described here.
API should be standardised (e.g. http://jsonapi.org/) and designed primarily for developers. Returning "Please return after a while" instead of "Internal Server Error" makes little sense to me. It's a 500 HTTP status response of uncertain reason e.g. NullPointerException somewhere deep in the code.

Is custom exception is better to throw from java client?

I have a microservices architecutre and few microservices have its own client in order for other services to easily use the service API.
In case when we need to return response to some service from our client we also can expect that something wrong might happens while client request and client could return some http status (for example 404(not found) in case if data isn't exist for a such request or 500(internal server error) in case of unexpected service error).
My question is which approach we should use for throwing exception from client?
Do we need to create a custom exceptions on client side and handle these in appropriate way? For example MyServiceBasicException, MyServiceResourceNotFoundException, MyServiceInternalServiceErrorException and so on?
Or we need to use already existing exceptions (for example from Spring ResourceNotFoundException that can be thrown in case if data isn't exist for a such request) or other libraries?
Which benefits have one and another approach?
Thanks in advance.
if you want to do some complex handling based on an exception type then you can extend one of the exceptions and do that. otherwise, if it's just for purposes of propagation i would say reuse.

JAX-RS client API: Why is the MessageBodyReader allowed to throw a WebApplicationException

According to the Javadoc, the readFrom method of a MessageBodyReader may throw a WebApplicationException, which seems strange as this seems only to make sense on the server side when parsing request messages.
But the same classes are also used on client side to parse response messages, which happens after the webservice has been called (which might be successful or not) and thus the readFrom method should not affect the HTTP status code in this case.
So why is the MessageBodyReader allowed to throw a WebApplicationException and how should it be handled by a client?
Eg. jersey-media-jaxb is an example which throws a WebApplicationException:
https://jersey.java.net/project-info/2.22.1/jersey/project/jersey-media-jaxb/xref/org/glassfish/jersey/jaxb/internal/AbstractRootElementJaxbProvider.html
The question arises since the client implementation provided by Jersey seems to have bug. I filed a related issue here: https://java.net/jira/browse/JERSEY-3005

What is the difference between UnauthorizedException vs OAuthRequestException in Cloud Endpoints?

In Cloud Endpoints, I understand that when doing OAuth I need to check if user == null to determine if a user has authenticated. In the case that the user is null I should throw an exception. In sample Google Cloud Endpoints code snippets I have seen two different exceptions being used though.
The OAuth documentation for cloud endpoints says to throw OAuthRequestException. However, I have seen other code bases (including a Udacity Course) throw UnauthorizedException.
I've noticed that OAuthRequestException does not extends from com.google.api.server.spi.ServiceException so Im thinking UnauthorizedException is the correct choice?
Which one should I use?
I would stick to UnauthorizedException' since it extends from theServiceException` class. As per the documentation at https://developers.google.com/appengine/docs/java/endpoints/exceptions and from API Best Practices, it is advisable to map the exceptions in a manner such that the correct HTTP Status Code is thrown.
So, in the case of the UnauthorizedException , HTTP 401 is thrown.
This is what I usually do in my code and I believe (and which you can try!) that you will see a standard catch all HTTP Error Code being thrown back in case you throw exceptions like OAuthRequestException that do not extend ServiceException (HTTP 503 or HTTP 500)

Categories