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.
Related
I am wondering what the correct way is to handle this type of request. I have a delete requests from a UI and it's a list of ID's which are integers. So the request can look like :
www.myui.com/delete/1,2,3,4
which is a well formatted request. But if the request for any reason came from a curl request or postman etc it may be formatted like:
www.myui.com/delete/1,,3,4
In this case the 2nd index will contain null since it's inspecting Integers. However if we were expecting a list of String it would be simple an empty string or an n amount of white space characters if it was formatted like /1, ,2,3, 4, so I would have to loop through the request and check if a string in the list of string is only white space and throw back a 404.
Should I be doing this in the controller or allow this type of request to pass on by and have the eventually have the exception thrown in the dao since it's going to try and delete an id that is either null or just white space which won't exist in the DB.
Below is an example of how I am currently handling the request which is a List of Integers.
#DeleteMapping(value="/delete/{ids}")
public ResponseEntity delete(#PathVariable("ids") List<Integer> ids)
throws DatabaseException {
if (ids.contains(null)) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
service.delete(ids);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
In short, fail fast is a better approach as it helps detect malfunctioning very early and quickly, although you might also consider business requirements and general design guidelines of your application, if it should be lenient, then you might go with something like:
service.delete(ids.stream().filter(Objects::nonNull).collect(Collectors.toList()));
and return a response body containing at least a number of items deleted.
If your application has to be strict, then a bad request should be returned as soon as possible as you are already doing.
Also, you have to take in consideration that your services and/or DAOs are not exclusively called from controllers, so validations and/or checks have to be implemented there as well, and try not to let malformed requests hit the database if you already know they would lead to errors, it would be just wasted traffic.
Finally, I hope the integer ids in your case are not DB generated, in which case it would be a major security issue since you are exposing persistence details over your api, an attacker could just wipe out your database or parts of it by just sending list of incremented integers. I would suggest you use some kind of randomly generated unique ids to expose over the api (this does not mean that you should get rid of integer base indices).
It is correct to handle the errors as soon as you detect them. In this case, the bad request is detected at controller level so it is the best option to handle it there.
Though your approach is fine, looking at #ResponseHandler may be instructive, as it can be used to generalize the handling of known exceptions, on Controller level.
After reading a lot about the abusive use of exceptions in Java and how you should let an exception bubble up through the different layers of an application, I've come to a point where I don't know what I am supposed to do with the potential errors my application can have.
Basically, I have a webservice which uses the DAO pattern to access data in my database. All of the database actions can throw a SQLException.
As of today, I'm using a try catch to catch the SQLException and then thow a specific defined exception called ExceptionDAO that will be handle by the webservice to return a correct message to the users (a mobile application) of my webservice.
After reading a lot about how exception should be exceptional and should not be used in control flow, I've come up with a mixed understanding of what I should do to handle any errors:
Use return codes for anything that is likely to happen (e.g. username already exists) and therefore, to comply with the DAO pattern, pass my business objects as parameters instead. I could also use a specific pair which would return the code + the business object instead. The webservice would then use the return code to display a specific message.
Use checked exceptions for anything that I can't predict will happen and let them bubble up to the webservice to handle and return a message to the users. (e.g. SQLException that I can't predict : connection aborted)
Let unchecked exceptions bubble up aswell and display a sort of 404 error in this case.
I also had a look at the null pattern but I don't think it suits this particular situation really well.
I'm also concerned to not give too much information to the users, but rather useful and straight to the point information. Indeed, the messages returned by the webservice will be used by a mobile application to then display a message to the end-user.
I hope that I was clear enough about the problem I'm having, and I'm looking forward to your answers !
Return codes are suitable for C, which lacks exception handling among its features. For Java, please use exceptions, either checked or runtime, that's a matter of taste.
Personally, I hate checked exceptions, because they pollute my method signatures with information of border cases that might never occur. But maybe you want to be strict with the contract of your classes, even for such exceptional cases. If that's your case, then use checked exceptions. Otherwise, let your method signatures in peace and throw a runtime exception whenever you detect an exceptional case (such as an entity not found, entity already exists, etc).
Please note that ExceptionDAO is not a happy name. It appears to be a dao that handles exceptions. Maybe something like PersistenceException would be better.
Apart from that naming detail, I think your approach is on the right way, though not ideal. Ideally, you wouldn't need to do a try/catch for SQLExceptions inside every method that calls methods from your DAOs (or inside every method of your DAOs). Instead, a persistence exception translation mechanism would be much better. Spring, for instance, comes with one by default. Spring accomplishes this by proxying every DAO, and by letting its proxies perform a try/catch around every method invocation. Then, specific SQLExceptions with specific SQL error codes are translated to Spring's own DataAccessException hierarchy. So, in the upper layers, you would end up with a specific DataAccessException, but you wouldn't need to do a try/catch inside every method.
If you are already using Spring, then you have nothing to do, but if you aren't using it and have either many DAOs or many methods that might throw SQLExceptions, and all your DAOs implement an interface, then it might be worth the effort to implement a proxy that intercepts all the methods of your DAOs and performs a try/catch around them. Then, in this interceptor's catch block, you'd throw your ExceptionDAO (please rename it!) with a message that would depend on the original SQLException (and maybe on its SQL error code, too).
This approach has the advantage that you could handle all persistence exceptions in a single point of your program.
This very same concept could be applied to your web layer as well. Instead of letting every method of your endpoints handle your ExceptionDAO (don't forget to rename it!), you could create a proxy that intercepts every method call and perform a try/catch around it. You could then extract the message from the exception and send it in the response (or whatever you find suitable to do with it). Again, this is all based in Spring, this time, in Spring MVC Exception Handling mechanism. Here you could also handle unexpected exceptions, i.e. RuntimeExceptions and provide an appropriate message to your users.
The advantage, again, would be that you could handle all the exceptions that reached your web layer in a single point of your program.
Please see Proxy javadocs and this tutorial for further reference on Java's proxies.
I think you are missing an important option, which is the observer pattern.
In your DAO you can have this:
public interface OnExceptionInteractionListener {
public void onExceptionInteraction(String exceptionMessage);
}
I would have the DAO be something like:
public SomeDAO(OnExceptionInteractionListener listener, ...) {
}
and I would instantiate the DAO as
SomeDAO s = new SomeDAO(new OnExceptionInteractionListener() {
public void onExceptionInteraction(String exceptionMessage) {
}
}, ...);
So, if there is an exception caught then call the listener in the DAO and the next level up will handle it.
This is better performance than throwing exceptions, and better than return codes.
For more on this you can look at this answer, for other examples: https://stackoverflow.com/a/18585099/67566
I haven't tried it but I expect that lambda expressions would be useful for this also, if you are using Java8.
Return codes are very old-school. Ideally, you should do your insert in some sort of transaction that checks:
Lock username inserts
Is this username available?
3a. If so, insert and unlock
3b. If not, unlock and inform user
If that's not possible, then a return object wrapping the result if it was created successfully and response Enum with potential outcomes.
I have the following method in my service layer.
public void delete(int candidateId) {
candidateRepository.delete(candidateId);
}
Pretty basic, now this method is used by the web layer which RESTful architecure is applied.
The URL that will trigger this method is:
DELETE /candidates/{id}
How should I deal with wrong ids given by the clients that use the REST API in the service layer? I know the HTTP response would be 4xx but how should I communicate that the id is invalid between the service and web layer?
Should I use a unchecked exception since this is a condition that my application is unable to recover from? The fault barrier (Spring exception handler) will deal with it.
Or should this be a checked exception since it is possible that clients give wrong ids?
I am using the latest Spring technology if that matter
If it is possible that clients give wrong ids, then they will give wrong ids. And this is a condition that your application should be able to recover from.
I would return a checked exception for this. But introducing a checked exceptions can sometimes mean changes throughout different layers of the application, because, for example, the signatures of many methods would need to be changed to add the "throws" clause (breaking OCP). In case that gets overcomplicated some people (like in Robert C. Martin's "Clean Code") recommend using unchecked exceptions. I would say it's up to you what to return as long as the exception has a meaningful description.
Firstly, you need to decide how your REST API will handle exceptions. There are multiple, equally valid solutions to this.
When designing an API, you pretty much have to assume that whatever can go wrong, will go wrong. Client applications will pass incorrect parameters, use incorrect formats, etc.; your application should expect this, and handle it gracefully.
Using exceptions to communicate business logic is not particularly readable, and may have performance implications. It really doesn't scale beyond very simple cases - imagine that the business logic for "delete" might need to include failures for "record not found", "record has dependent relationships", "record protected", "record archived" etc.
Instead, I would design the application to pass explicit status information back and forth, and translate this into whatever RESTful error handling you use.
In a CRUD jsf application, owners have objects, like records.
I want that owners can only view/edit/delete objects created by themselves. One way to achieve this, in every method to check if object has been created by the logged user.
There can be many similar methods and objects, so I would like to use another elegant/automatic way instead of using
if (selectedObject.owner == loggedUser)
phrases in every methods.
Is it possible,if possible how?
You could use aspect oriented programming for access protection.
I'd write an aspect to intercept all method calls to the access restricted methods, apply the check in a before advice and throw an exception if it fails. Depending on the structure of the program either by looking for an explicit annotation or by using a rather generic pointcut.
This would move your if (obj.owner.equals(loggedUser)) to one central place, but of course you'd still need to take care not to include other users' items in lists etc.
"The" Java aspect implementation is AspectJ. It is also used and supported by the Spring framework, which you may already use anyway: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html
If I were you I would show the component only if the user is authorized, by using
rendered={user.isOwner}
You will use this as an attribute in your component.
Although I have tagged this as a java/spring question it can be easily asked of any mvc framework with stateless controllers. I know rails uses simple stateless controllers for instance so perhaps you guys know how to best solve this problem. I can best describe the problem with java/spring mvc which is the implementation - forgive the java jargon.
The issue
We are having trouble coming up with a satisfactory way of performing stateless-to-stateful handover in spring mvc.
In essence given a structure like:
Model: Unit
With the states: withdrawn, available, unavailable
And the operations: getOutline() and getHelp()
Controller: UnitController
with operations: displayOutline() and displayHelp()
We need a way to check the state of the unit before we execute the operation displayOutline() (because the unit itself may be withdrawn and so the user should be forwarded to a withdrawn page).
We have tried to do this a number of ways including:
The dead simple way (any language)
All methods in the controller that require an ‘available’ state unit call a method isAvailable() in the first line of its implementation. Obviously there lots of replication here, it reeks.
The AOP way (Java specific)
An #Around advice can be created called UnitAccess which does the check and reroutes the control flow (i.e. instead of calling proceed() which would invoke the underlying method it calls another method on the controller). This seems like a hack and not really what AOP if for, it does remove the replication but adds complexity and reduces transparency.
An Interceptor (Provided by servlet architecture but probably doable in other frameworks)
Which checks the unit state and essentially changes the actual URL call. Again this does not seem right. We don’t like the idea of invoking model logic before getting to a controller.
We have thought about
Command Pattern
Creating a command pattern structure which (with the use of inheritance) can return a withdrawn view or valid displayOutline view. As the execute method will perform the checks in a super()call and the specific logic inside the concrete commands. Ie creating a object structure like
DisplayOutlineCommand extends UnitCommand
public void execute(){
super();
// must be ok, perform getOutline()
}
And finally, using a custom Exception
Calling getAvailableUnit() on a service level object which will do the checks for availability, etc before returning the unit. If the unit is withdrawn then it will throw a UnitWithdrawnException which could be caught by the servlet and handled by returning an appropriate view. Were still not convinced. We are also not hot on the idea of using an exception for normal flow control.
Are we missing something? Is there an easy way to do this under spring/another stateless controller framework?
Maybe I'm missing the point, but why should a user come to the controller if the Unit is withdrawn?
I would argue it is best to ensure that normally pages don't link to a controller that require the Unit to be 'OK', if that Unit is not 'OK'.
If the state of the Unit changes between the time the referring page is rendered and the actual call comes in to the controller (it is not longer 'OK'), then the use of an exception to handle that event seems perfectly fine to me (like having an exception when an optimistic locking error occurs).
Perhaps you haven't described the whole problem, but why not put the check in displayOutline() itself? perhaps route to a displayOutlineOrHelp() method, which looks essentially like
ModelAndView displayOutlineOrHelp(...) {
Unit unit = ... //code to get the unit the request refers to
return unit.isAvailable() ? displayOutline(...) : displayHelp(...);
}