How to handle Exceptions in Rest API whit Spring boot - java

I need to handle the exceptions in My rest API.
I have a layered architecture, composed by Entities, DAOs, Services and controllers.
In my services I have the model Exceptions, and I need to know the best way to translate these exceptions to send responses in HTTP.
I read about Exception handler and Controller advice but I'm not sure how is the best form to do this.
Anyone can iluminate me?
Thanks

I would go with #ControllerAdvice for most of the exceptions, for instance, validation error, system errors etc. On the other hand, you could use error handlers for specific cases in your controllers.
This way you have generalized error handler with the possibility to overwrite the default error handling.

One way is by the use of spring ExceptionHandler (there are several variants possible depending on spring version).
Some good documentation here

best way is to create your own custom exception class and dont handle any excpetion in dao & services instead of just throw custom exception from there
and handle all excpetion in controller and response back meaning full message to client from controller.

Related

ExceptionMapper advantage in jersey

I am new to Jersey framework. Just want to know what are the advantages of using exception mapper.
If I want to throw any error to the rest consumer I can do the following in the method,
Response.status(502).entity("Server error during registration").build();
Why it is recommended to use exceptionMapper, please help me understand?
In the particular case of your example, it will have the same effect.
In case the exception is not thrown by you directly but in some code you are calling, for instance from a library, you would have to catch that exception to "map" it manually, in order to have the desired behavior.
Now if you want to treat different kind of exceptions in different ways, you will probably need to have several catch blocks, or use instanceof intensively. And for each new entrypoint of your service, you will have to repeat this exception handling business.
ExceptionMapper is just a clear/scalable way to intercept potential exceptions that may be thrown within the implementation of your service.

Java Throwing exceptions vs returning response in catch

I know a lot has been discussed around exception handling, however I need some advice specific to my situation.
I am currently working on a Spring MVC application with Controller->Services->DAO layers. The service classes catch mainly two kinds of exceptions HibernateException and IOException.
HibernateException because service needs to perform rollback if a transaction did not succeed and IOException since it is an unchecked exception and needs to be caught or thrown and I prefer the first option.
Now what would be a better way of handling these further up in the stack :
Should I rethrow these exceptions to the controller and in the
ExceptionHandler of the controller send a HTTP error-code 500
Or in the catch block create the normal JSON response object, setting status=failure and the appropriate error message and return this to the Controller?
Exception Handling convensions:
There is a saying that, best way of handling Exception is not to handle it!
For Spring's convention of controller<->service<->dao layers, Exception handling mechanism is known as Bubble up. Any exception occurs in the dao or service layer, you should pop it up to the controller layer (by adding throws XXXException in dao and service layer's method signature, is the most common way). Only controller layer should handle Exceptions.
Here is a nice tutorial of how you can handle exceptions for REST with spring.
Send HTTP Status code 500 or JSON object with status:
Sounds like you are writing API with Spring MVC. Look, when you are writing API's you should follow the proper conventions. It is Globally accepted that for internal server errors you send HTTP response with code 500, that means internal server errors.
There are number of causes for what you should not send JSON response in this case. One of the main cause is the implicit assumption of your API client. That is HTTP response with code 200 with a JSON object means every thing went normal. And thus the client side business logic may reflect that assumption which is wrong eventually.
Here you can see some API error code conventions for some well-known organizations:
twitter
LinkedIn
Facebook Graph API
I assume that you have not come so far yet as to create a client and therefor can pick 100% for yourself.
If so I would also recommend to use 1, for the main reason that using the correct status codes can go a long way in your API, as well as it's a very easy solution to your problem. You can write some neat code for your error handling.
Another major reason why you should use your first point is because you can easily re-use the error handling for other APIs, resources or webapps.
For example an enum with all your errors, and what status code you consider them to be, and you can also include what log level you want them to be.
public enum ExceptionMapping {
IllegalArgumentException(IllegalArgumentException.class, 400, LogLevel.ERROR),
If your goal is to build a neat API for unknown clients I would recommend reading more about REST level 3 (http://martinfowler.com/articles/richardsonMaturityModel.html) where you includes hypermedia links to create an API which allows the client to "browse" your full API. It's more work for the client since they have to be smarter but it can provide you with very nice features such as breaking a large part of your API without the client even noticing.

CXF InFaultInterceptor vs. OutFaultInterceptor

I am working on REST API with CXF framework. Anybody can explain to me more detail about what's different between InFaultInterceptor vs. OutFaultInterceptor? They seems belong to different phase of interceptor. But Do we should put what logic into different Fault Interceptor? I need to abort interceptor chain and response custom response message. I cannot see different on InFaultInterceptor and OutFaultInterceptor for my scenario. What's your typical error handler interceptor? Could you brief introduce your error handling structure of CXF if convenient?
The concept in the interceptor chain is pretty straightforward, in is coming in, out is going out.
For instance, if you want to change the way faults are populated in a SOAP Fault, say to get some variable you are putting in the exception you are throwing, you would use say the Soap12FaultOutInterceptor to modify the fault you are generating. The Soap12FaultInInterceptor would be used to handle incoming faults.
My real question is why do you want to use the interceptor chain, and what is your use case? This is not unusual, but many times unnecessary especially with Spring and aspecting, IMO.

Java: Error handling in MVC project. How correct implement?

For example: we have WebApplication based on MVC. Also, for this app we are used: Spring, Struts 2 and Hibernate frameworks.
Lets go look on small scenario: user try save some instanse, for example: BO Book.
So, user fill form fields and send request to the server:
What happened on server?
Execute action method Action.Save();
Inside Action.Save() call Service.save();
Inside Service.save() call DaoHibernate.save();
Inside DaoHibernate.save() call getHibernateTemplate().save();
Method getHibernateTemplate.save() - it is framework implementation, so we cant access to this method. We only know, that if something fail inside this method throws DataAccessException.
So, at this moment I think, how correct implement my logging and error handling?
On which level?
On Dao level? Service level?
Or on level Struts actions?
What do you think about this?
Or need on each level?
What best practices you can recommended?
Here is your architecture:
How do you want to handle the error on DAO layer? Return fake data? Empty collection? if you can't, just let the exception pop-up.
And how about handling on the service layer? You know that the database is not working, so what can you return to the Struts action? An empty result? An error object? Isn't exception an error object?
So the exception appears in the Struts action. Here you have some options. If the exception will actually tell something to the user and your GUI is prepared, you can return different view (and log the exception here).
But what if you catch a NullPointerException in Struts action? Will you handle it separately in every Struts action? No, so pass the exception even further (!)
I think you get the idea - as long as you don't know how to handle the exception (and logging is not handling), let the client clean-up the mess. Otherwise you are only hiding the problem and increasing the damages (e.g. transactions aren't rolled-back, users see incorrect results).
I would advice implementing generic exception handling mechanism which logs the exception and returns HTTP 500 to the user. Gentle error message (without stack trace) should appear and the user should be apologized. You should investigate every error that reaches this layer.
As far as I remember Struts (and virtually every web framework) has some centralized way of handling exceptions. (Struts 2 Exception Handling Docs)

Handling Exception like validation errors in Spring MVC

I have configured the SimpleMappingExceptionResolver in my web application, which is handling all the unexpected exceptions in the application and directing the user a to simple error page for recovery.
But what would be a best practice of handling an expected exception (more specifically: exception caused by hibernate optimistic concurrency control)?
I don't want the user to be directed to a new error page, but allow him/her to continue working in the same jsp page. What is the best method to achieve this?
Assuming Spring 3, you can annotate methods on your Controller class with #ExceptionHandler to define what should happen when particular types of exceptions come out of your handler methods. The signature is not quite as flexible as #RequestMapping methods, but you can generally manage what you want. (Which in this case sounds like just add an error message to the model map and re-run the method that handles GET)

Categories