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)
Related
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.
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.
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)
I'm using spring-mvc and my controllers mostly contain too much logic. When 3 - 5 service beans constitutes the business process and they are called in one handler, then there is some validation included and it results in a few if-else conditions with positive or negative response.
One possible solution is having a facade that contains all references to service beans and common interface of their methods. This makes it simpler, it can also constitute exception boundary in the MVC pattern, but still, the business process has some logic and validation and it is still dealt with in the handler method.
Should I create something like this? :
BusinessProcess {
processOrder() {
serviceBeanA.call();
result = serviceBeanB.call();
validator.validate(result); // throw exception
serviceBeanC.call(result);
}
}
and use only BusinessProcess bean in my handlers ? Catching exceptions or return value would say what's wrong and what to include into the response. Otherwise content of processOrder method would be in handler.
Is it correct way ? How is this pattern called if so.
Most likely you should do as you suggest if I understood correctly. I don't think there's a name for this "pattern" nor needs to be. Since you seem uncertain, here's why I think you are thinking about the right thing.
Processing orders is an logical abstraction your handler is interested in. How the OrderProcessorBean (or BusinessProcessImpl) actually accomplishes this is an implementation detail and hidden from the handler/controller.
Not having such bean you may write a method processOrder in some controller and the controller has dependencies and references to service beans dealing with the details of processing orders. As you noticed this is not good design.
It also seems proper that the processing code lets exceptions fly out and is not bothered how they are handled by the caller. Perhaps a transaction is rolled back and perhaps some HTML containing error messages gets serviced to the end user, but the code (business logic) responsible for processing orders should not know that there are such things as Spring MVC or HTML.
I am currently adding functionality to a JSF/Richfaces application and we are now integrating with external web services.
Actions done with the services include: get user, get account, update user, update account, create user, create account.
These services, along with the unexpected soapfaultexceptions, can return error codes in their response types. Mainly for failures along the lines of: login already exists, password doesn't meet criteria, account number already exists, and no user found.
The calls are like so: BackingBean > Manager Level Class (mainly a pass through) > Web Service Client (makes the actual WS call). For the GET actions, the ID (username or account number) is passed down and the Account or User object is passed back up. The Updates pass around User/Account objects, same with the Creates.
What would be the best way to get these errors back up to the backingbean so I can handle them via the UI?
Of course I could check for error codes in the response, throw an exception and keep throwing it to the backing bean where I would handle it there.
I could implement a Result type that would hold an Error Type and POJO/DTO that I was populating from the service.
One of my colleagues recommended I use the decorator to decorate my USER or ACCOUNT objects with validators that I would also need to create. Basically I suppose my decorator would just hold custom Error types and the Validate() would just check to see if (List!= null && !(Size>0)). Correct?
What are your thoughts on the proposed methods? #1 is the easiest, #2 seems to be more elegant and still simple, #3 is the "toughest" to me since I've never used the decorator pattern. However, #3 seems to be the most elegant while also being the most time consuming to implement.
Let me know if you need any more clarification.
Thanks, SO!
It's always best to limit programatically using exceptions(When to throw an exception).
First ask yourself is this an exceptional situation? In your case it isn't its just a validation error. Exceptions come with a cost, and there is no guarantee that you will be able to catch the exception further down the chain.
Both 2/3 are similar solutions in the fact you are just trying to return additional information back to the controller.
Option 3, could be considered cleaner, but if you have access to the user/account classes, you could always add an additional property to the class that could contain validation errors.
A good example of this pattern is ActiveRecord within ruby, same type of model. You call save on a model object, if an error occurs it populates an error property.
Throw a custom exception or one of a set of custom exceptions and handle it at the higher level. This is my preferred way of handling it versus status codes in Java where everything is pass by value, and frees up a return variable for other purposes.
In regards to "keep throwing it," don't catch and re-throw at each level, but only catch at the level where you can do something about it, ie. the backing bean / UI in this case.