My application architecture can roughly be represented like this:
UI --> Domain Model --> PersistenceService (Caching etc.) --> Mapping Layer
The Mapping Layer consists of interfaces that are like DAOs (just get, insert, update and delete), The Persistence Layer uses these interfaces and adds caches and checks to avoid unneccessary updates.
In theory, there are various implementations for the Mapping Layer, for example, one could map to xml files or to an SQL database; but because the mappers interact with the "outside world",
they usually throw checked exceptions (IOException, SomeSQLException ...).
First problem is, how can I unify my Mapper interfaces, if the Exceptions are different for each implementation? I could create a new exception (MapperException) that can be thrown, and then I would "bubble up" the exception, through my persistence layer, through the domain layer, until the UI catches it and displays a (generic) error message.
And here is the thing I don't like; the exceptions are checked exceptions, however there is no class or layer that can actually handle them, they are just passed up until they are displayed and thats it. It seems weird to have a throws-clause on nearly every method, just because some of the low level classes throw checked exceptions that should be handled.
Can I just convert the checked exceptions to unchecked exceptions? How would I make sure that they are still catched in the UI?
Or can I somehow inject an exception handler into the lower layers that is provided by the UI layer?
Is there some kind of best practice to this? So far I have rarely dealt with exceptions because the usually do not occur and I didn't care about proper exception handling in my earlier private projects.
IMO Lower-layer exceptions should generally be caught and wrapped in application-specific exceptions; exception chaining ensures the root cause is captured.
This protects the upper layers from changes in underlying functionality, e.g., if you have a general DataLayerException, the underlying persistence mechanism(s) can be swapped at will, and the upper layers don't need to change how they deal with persistence-related exceptions. This also allows multiple persistence mechanisms at once, like both relational and NoSQL datastores to report exceptions in a unified way to the upper layers.
Note that some frameworks already handle some of this exception aggregation already.
Converting to runtime exceptions may or may not make sense, but runtime exceptions can be caught as long as you know they're being thrown (or may be). It really depends on your specific needs.
Can I just convert the checked exceptions to unchecked exceptions?
Yes of course, just wrap it in a RuntimeException of your choice:
try{
// something unsafe happens here
} catch ( SomeUglyCheckedException suce){
throw new UncheckedExceptionOfChoice("Something went wrong", suce);
}
How would I make sure that they are still catched in the UI?
Probably yes, but it depends on the technology you use. You might register an ExceptionHandler on threads involved: http://www.javapractices.com/topic/TopicAction.do?Id=229 or the framework you use might provide a special mechanism for that.
Related
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 understand throwing exceptions specific to the application layer you're in, but what is the purpose of all of this exception handling overhead if you're:
Just going to let the exceptions bubble up to the top.
Never going to do anything "unique" with the wrapped exception.
For example, I have a DAO that throws a SQLException, and the next layer up is a manager that calls the DAO. The commonly accepted paradigm is that I create a manager exception, wrap my SQLException, and then throw the manager exception. Why? If another class up the chain is going to deal with it anyhow, then why wrap it?
In your example, it might not be useful. But suppose you're writing an interface with many possible implementations. Suppose for example that two years from now, you switch from a SQL database to a NoSQL one. Your DAO will then be forced to declare NoSQLException, and all the calling code will have to be rewritten. Whereas if the SQLException or NoSQLException is wrapped inside your custom exception, the calling code can stay as it is.
In your specific example, if you have a service layer that calls the DAO, you don't want clients to see SQL Exceptions such as "ORA-00118: unique constraint (BLABLA) violated".
Making such exception messages meaningful to upper level layers is one reason why you might consider wrapping them into more meaningful exceptions.
Catching and re-throwing is not handling anything. Better to let it bubble up in that case.
Catching a checked exception and re-throwing as unchecked can be a useful thing to do, but it's better to add more specific information.
You should only wrap and throw an exception if you're going to add some useful info to it, or to make it specific to your domain. Otherwise you should just be letting an exception bubble up to where it can be handled. I'm guessing that you're looking at some suspect code for your examples.
One example for wrapping exceptions, that might actually be useful, is to "convert" implementation-specific exceptions to something more specific to a framework in an IoC/DI scenario. For example, if you have a framework that does some work, you want to shield the client code from having to "know" a bunch of specific exceptions. So you create a set of common exceptions that your plug-ins throw and that your client code knows and can handle. Like data access exceptions for a bunch of different back ends.
java enforces you to explicitly declare which exceptions can be thrown. wrapping exceptions prevent:
1. expose what is your specific implementation (the higher level might not know that you are using sql as your data base, so you can just throw MyAppException).
2. otherwise, the list of declared exceptions would increase overtime, which will enforce the higher level to take care of all of them, which might be not very neat.
I think it all depends on how specific you want to be and if you want to include more information in your custom exception. Otherwise, you can just allow exceptions thrown by other methods to bubble up and handle them however you see fit.
In your case, SQLException might be too generic, so wrapping it in your own custom exception can help more easily determine where it was thrown in your application and to include more specific information.
So different implementations of the DAO using different datastores can transform the different storage-specific exceptions to the same abstracted storage exception. Then they just include the original for debugging purposes.
I would suggest that in many cases, exceptions could be most usefully handled by reducing them to three types:
OperationFailedStateOkException
The operation could not be completed, but the local and global system state is okay except to the extent implied by that failure (e.g. trying to reference a non-existent item in a Dictionary).
OperationFailedLocalStateCorruptException
The operation could not be completed, and the local system state is corrupt (e.g. trying to reference an item from a corrupted Dictionary).
OperationFailedGlobalStateCorruptException
The operation could not be completed, and the global system state is corrupt (e.g. a shared cache got corrupted).
Note that in many cases the caller of a routine won't be nearly as interested in why it failed as in what the failure implies about the state of the system. Exceptions of the first type may generally be safely caught, and execution resumed, if the programmer knows why they might occur and what to do about them. In some cases, they may need to be rethrown as exceptions of the second type (e.g. if the system was unable to perform some operation which would be necessary to maintain consistency in a data structure). Those of the second type should only be caught and rethrown as the first type at a level where the corrupt state is going to be abandoned (e.g. a "Load document" routine might catch such exceptions and rethrow as a "state ok" exception if any corrupt data structures used in the failed attempt to load a document are going to be jettisoned). Those of the third type should generally trigger a program shut down.
To be sure, it may be useful to have some gradations between the different types (e.g. indicating a global problem sufficient that the program should be shut down gently, saving user data, versus indicating that things are so bad that attempting to save user data would corrupt things worse). Nonetheless, catching exceptions and rethrowing one that indicates something about the system state may be nicer than simply leaving higher levels of the code to wonder what to do with an InvalidArgumentException.
I'm currently writing an Java Wrapper for a RESTful web services API.
I'm now trying to clean up some of the exception handling, and not sure what approach to take. This is a tool intended to be used by Java programmers, so I can't really handle it the same way I would with a end-user application.
If I have a method (connection) that contains code that could throw exceptions, how do I get those exceptions to float up to the end-programmer? and is this even the way I should handle it, depending on them to catch the exceptions? etc...
I suggest you catch the exceptions from the underlying API (unless they really make sense to allow through), and throw a new exception which is more appropriate for your level of abstraction.
Use exception chaining if you don't feel like discarding the cause of the exception.
I think you should decide whether the existing type is specific to the implementation, or inherent to the library. For example, if it's a network related exception and you're obviously making a network-based API, I'd just let it propagate up. The caller needs to be aware of that sort of error anyway.
On the other hand, if it's a database-related exception which is only possible because for some bizarre reason you're looking up the WSDL in an embedded database, or something like that, that's clearly inappropriate for the caller to have to deal with - so catch it and wrap it in an exception which is more appropriate to your abstract level.
You will have to pass the exception to the user in any case since it's a library.
If you are not logging and are not planning to create custom exceptions, then you just don't have to handle the exception.
if you are logging, handle the exception and rethrow the exception.
if you have custom exceptions, make sure it have take exception a constructor parameter and then link the current exception to your current exception and then throw custom exception. This is required to maintain the useful stack trace information.
The question is how opaque you want your library to be.
Every exception type that you throw to your users should imply the user can do something about it. For example,
catch (ConnectionException e) {
disconnect();
connectAgain();
}
only works if your users have access to disconnect() and connectAgain(). If, however, you promise to provide all kinds of connectivity, your code should already have this logic, and if that fails, throw a generic WrapperException and be done with it.
Possibly a good approach for you would be declaring your own type of exception (and don't make it a RuntimeException), catching the exceptions you observe and throwing your exception instead.
I think its important what the API does, and in which context it is used.
If the API is part of your presentation/rendering layer, then I would prefer to always return something that is ready to be rendered, decorated, or written to the response stream.
If the API is meant to perform (non-rendering/UI related) processing, I would have no problem throwing up any exceptions outised the scope of the API logic.
If the API is designed well, these would be causes that are clearly beyond the control of the API, or logically beyond the scope of what the API "knows how to" or "should" handle, even if it could catch/control it.
When returning an exception to a "user" I prefer returning standard exceptions whenever possible rather than a single custom wrapper type.
Within my API implementation however, I use custom exception types frequently if they serve a clear and useful purpose.
just my 2 cents :)
This is more of an OO design question.
So, I've got an UnsuportedLocaleException which will be used only on the initialization stage of an app. I've got two options:
Extend RuntimeException and leave it out there without any handling logics (acts as a config => apply defaults if wrong).
Extend an Exception and handle it (involves all the redundant coding etc.).
I like the first one more, but not sure if that'll be correct design.
Seems entirely reasonable to me. RuntimeException is a good base class for exceptions which calling code shouldn't try to "handle" - i.e. when they indicate the kind of failure which probably means that either the whole app or (possibly, for servers) the request should simply be abandoned.
The first one is fine. There are many exceptions that subclass RuntimeException.
There is several opinions here.
First (classic) says that in most cases you should use checked exceptions. In this case methods must either declare this exception as a part of its signature or catch it. This method has advantages that the interface is always clear and each layer care about its exceptions. But the method is pretty verbose. Sometimes your code becomes much longer, you have to right several try/catch statements instead of call a coupe of methods and write one if.
Other approach is to use runtime exceptions only. This philosophy says that you do not have to handle exceptions because you have nothing to do with them. In this case all exceptions are runtime and are caught and processed in one central module. For example Spring framework uses this approach.
So the answer is what are you developing. If this is stand alone library use checked well defined exceptions. If it is application or application framework you can use the runtime exceptions like Spring.
Seeing a checked expection in API is not rare, one of the most well known examples is IOException in Closeable.close(). And often dealing with this exception really annoys me. Even more annoying example was in one of our projects. It consists from several components and each component declares specific checked exception. The problem (in my opinion) is that at design time it was not exactly known what certain exceptions would be. Thus, for instance, component Configurator declared ConfiguratorExeption. When I asked why not just use unchecked exceptions, I was told that we want our app to be robust and not to blow in runtime. But it seams to be a weak argument because:
Most of those exceptions effectively make app unusable. Yes, it doesn't blow up, but it cannot make anything exepting flooding log with messages.
Those exceptions are not specific and virtually mean that 'something bad happened'. How client is supposed to recover?
In fact all recovering consists from logging exception and then swallowing it. This is performed in large try-catch statement.
I think, that this is a recurring pattern. But still checked exceptions are widely used in APIs. What is the reason for this? Are there certain types of APIs that are more appropriate for checked exceptions?
There have been a lot of controversy around this issue.
Take a look at this classic article about that subject http://www.mindview.net/Etc/Discussions/CheckedExceptions
I personally tend to favor the use of Runtime exceptions myself and have started to consider the use of checked exceptions a bad idea in your API.
In fact some very popular Java API's have started to do the same, for instance, Hibernate dropped its use of checked exceptions for Runtime from version 3, the Spring Framework also favor the use of Runtime over checked exceptions.
One of the problems with large libraries is that they do not document all the exceptions that may be thrown, so your code may bomb at any time if an undocumented RuntimeException just happens to be thrown from deep down code you do not "own".
By explicitly declaring all those, at least the developer using said library have the compiler help dealing with them correctly.
There is nothing like doing forensic analysis at 3 in the morning to discover that some situation triggered such an undeclared exception.
Checked Exceptions should only be thrown for things that are 1) Exceptional they are an exception to the rule of success, most poor exception throwing is the terrible habit of defensive coding and 2) Actionable by the client. If something happens that the client of the API can't possibly affect in any way make it a RuntimeException.
There's different views on the matter, but I tend to view things as follows:
a checked exception represents an event which one could reasonably expect to occur under some predictable, exceptional circumstances that are still "within the normal operating conditions of a program/typical caller", and which can typically be dealt with not too far up the call stack;
an unchecked exception represents a condition that we "wouldn't really expect to occur" within the normal running environment of a program, and which can be dealt with fairly high up the call stack (or indeed possibly cause us to shut down the application in the case of a simpler app);
en error represents a condition which, if it occurs, we would generally expect to result in us shutting down the application.
For example, it's quite within the realms of a typical environment that under some exceptional-- but fairly predictable-- conditions, closing a file could cause an I/O error (flushing a buffer to a file on closing when the disk is full). So the decision to let Closable throw a checked IOException is probably reasonable.
On the other hand, there are some examples within the standard Java APIs where the decision is less defensible. I would say that the XML APIs are typically overfussy when it comes to checked exceptions (why is not finding an XML parser something you really expect to happen and deal with in a typical application...?), as is the reflection API (you generally really expect class definitions to be found and not to be able to plough on regardless if they're not...). But many decisions are arguable.
In general, I would agree that exceptions of the "configuration exception" type should probably be unchecked.
Remember if you are calling a method which declares a checked exception but you "really really don't expect it to be thrown and really wouldn't know what to do if it were thrown", then you can programmatically "shrug your shoulders" and re-cast it to a RuntimeException or Error...
You can, in fact, use Exception tunneling so that a generic exception (such as your ConfiguratorException) can give more detail about what went wrong (such as a FileNotFound).
In general I would caution against this however, as this is likely to be a leaky abstraction (no one should care whether your configurator is trying to pull its data from the filesystem, database, across a network or whatever)
If you are using checked exceptions then at least you'll know where and why your abstractions are leaky. IMHO, this is a good thing.