I'm working on a message library and the send method of an object can fail for a number of reasons such as the socket being closed, etc.
I favor checked exceptions over runtime exceptions but I'm wondering if it would then be more appropriate to favor chaining the exceptions early such that the underlying exception is always wrapped in another, more generalized exception.
For example, a message may only throw a checked SendFailedException but the cause() would be more specific such as SocketClosedException. This feels like it would be less cluttered than having all of the checked exceptions being thrown individually.
Inheritance doesn't quite work here as a SocketClosedException can be thrown for other methods as well. And not every closed exception is a result of a failure to send.
Would it be appropriate to wrap further information in cause() or would this end up being more confusing? I don't recall finding exceptions functioning in this way in the wild and this might be unconventional and confusing for others.
Does Java or other libraries ever do this? Is it appropriate for my use case?
Would it be appropriate to wrap further information in cause() or
would this end up being more confusing ?
You can always use cause to wrap the original exception which will provide more details about the root/origin of the exception in the stacktrace. You can refer Exception API here which explains how cause can be set to wrap exceptions.
Does Java or other libraries ever do this? Is it appropriate for my
use case ?
In many libraries, this pattern is followed, just to pin point, in spring-mvc, NestedServletException will be thrown by the container which will wrap the original exception with the cause. Yes, in your case, you can throw SendFailedException by setting the cause as SocketClosedException.
Also, if your message library is from third party, ensure that the 3rd party Exception classes don't spread across your project/classes, rather wrap/convert them into your own Exception classes so that your code is not tightly coupled with 3rd party Exception classes (even if you have to migrate from it).
Related
I've been a Java developer for about two years now and if there's one thing I really love about the language it's the stream API. It makes my code so much more fluent, consise and readable.
The one thing that bothers me though is how exceptions are supposed to be handled when working with lambda's. I've read several articles on the subject and have seen several questions on StackOverflow.
The general consensus seems to be that you have to wrap the method call to catch the checked exception and rethrow an unchecked exception instead.
(like so:https://www.oreilly.com/ideas/handling-checked-exceptions-in-java-streams )
But I've yet to read or understand why this is a good idea. The advantage of checked exceptions is that the caller knows what to expect. I was taught that whenever you want to enforce business rules, checked exeptions is the way to go. Unchecked exceptions should be reserved for those cases where the application cannot recover from the exception. So why did they pretty much force us to use unchecked exceptions when working with streams? This seems like a big flaw at first glance, right?
I'm currently writing a SOAP webservice and a big advantage is that all possible business faults that can be thrown are well defined. The client can respond accordingly to the exceptions being thrown.
Throwing a runtime exception would cause the client to receive a SOAPFaultException not knowing what the heck went wrong or how to handle it.
I could use a global exception handler and catch all the possible RTE's (given I don't forget some) and then once again rethrow them as one of the checked exceptions defined in the XSD/WSDL.
But I have a hard time enough convincing my senior colleagues of the benefits of functional programming and telling them to wrap their checked exceptions in unchecked exceptions, only to turn them back into checked exceptions is definitely not going to help my plight.
So why is catching checked exceptions in lambda's and wrapping them in unchecked exceptions considered the good way to do it? There are very few other scenario's where we would really catch a checked exception and throw an unchecked exception.
So why is it considered to be the good option when working with lambda's?
Is it really because it is the only possible way to do so (safe for a few dirty workarounds like Lombok's #SneakyThrows) given the language's limitations?
And then how are you to handle all these unguided missiles?
Why should you wrap checked exceptions in lambda's in an unchecked exception?
Short answer: because you have to. (Pretty much.)
So why did they pretty much force us to use unchecked exceptions when working with streams? This seems like a big flaw at first glance, right?
Without going into the history and the debate about whether checked exceptions were or were not a mistake ...
The handling of exceptions in streams and lambdas is actually a direct consequence of the general design of Java exceptions and exception handling. The latter cannot be changed: it would be too disruptive for Oracle's existing Java customer base. Therefore we are stuck with this for the foreseeable future.
Is it really because it is the only possible way to do so (safe for a few dirty workarounds like Lombok's #SneakyThrows) given the language's limitations?
Yes, it is the only way. Whether it is a good way or not.
And then how are you to handle all these unguided missiles?
One way is to simply let the unchecked (or sneaky checked) exception propagate. In most cases the application or thread will crash, and you can use the stacktrace in the log file to find / fix the root cause. This assumes that the original checked exception is not "expected" and therefore not really recoverable.
If you are trying to make your application recover from the checked exception:
For a wrapped exception, you can catch RuntimeException then use ex.getClass() and ex.getCause() to decide what to do.
For a sneaky checked exception, you can catch Exception and use instanceof to discriminate the (expected) sneaky checked exceptions from the unchecked ones.
Does it make sense to immediately wrap and throw exceptions to provide more context/reason as to why the exception was thrown?
For example, assuming CustomException is a custom exception for the particular application/module:
throw new CustomException(new UnsupportedOperationException("Feature X is no longer supported. :("));
Would it be more standard to simply pick one or the other? For example:
throw new CustomException("Feature X is no longer supported. :(");
or
throw new UnsupportedOperationException("Feature X is no longer supported. :(");
I understand that it's fairly standard practice to throw wrapped exceptions if they're being rethrown / from a catch block but I don't think I've seen throwing wrapped exceptions from scratch (using new).
I can't think of a case where creating a wrapped exception like this is a good idea.
Filling in stack traces is relatively expensive, and creating a duplicate stack trace is a waste.
Exception chaining and suppressed exceptions are primarily for logging; applications that inspect this information in order to control flow are fragile. Any extra information you want to convey can be put in the message for logging with the stack trace.
The exception mechanism is based on the exception type, and handlers should primarily rely on that for flow control. If additional information is needed, it can be exposed through specific API on the custom exception.
In the case of a deprecated API, throwing UnsupportedOperationException is the best choice. It is a programming error to upgrade a library to an incompatible version. This doesn't occur unpredictably at runtime; the developer can and should discover this problem during development.
If runtime exceptions are caught, it should be at a high level in the application. For example, a Servlet engine might catch and report runtime errors without aborting the whole process, protecting other applications. A GUI might catch runtime exceptions arising from event dispatch without crashing the whole application.
In other cases, throwing a new CustomException might be better. A subclass of CustomException could be used to report a type of error that might be recoverable. For example, suppose usernames must be unique. Your application could check to see if a username is taken, and then create an account if the name is available, but this introduces a race condition where another user might claim that name in the meantime. By attempting optimistically to create the user account, and failing with a specific DuplicateUsernameException if the username is not available, a handler can prompt for a new username.
For your case I would say
throw new CustomException("Feature X is no longer supported. :(");
Unless you want top level component to know what you are throwing.
This can be either
1. DAO related
2. Any exception would cause another exception
3. multiple exception would occur
For example if this feature X if yours might throw IOException and FileNotFoundException. You dont want to return both to the upper component then you should wrap it. But you know the feature X doesn't have any impact to the caller class then you can just end it with the custom exception.
Does it make sense to immediately wrap and throw exceptions to provide more context/reason as to why the exception was thrown?
When you catch an exception and wrap it, this makes perfect sense. Adding the context information is one reason to do it. Another reason is to make it a different kind of exception altogether in order for it to be suitable for the callers of your API (as opposed to being suitable to your API's implementation).
Consider an example: your library uses an RDBMS backend to store some data, with referential integrity constraints turned on. One of these constraints could reject duplicate records of some kind for the same user ID. In this case your library would catch SQLException indicating that the referential integrity constraint is violated. However, your library should not throw SQLException to its users. Instead, it should throw a custom DuplicateUserRecordException with user ID and SQLException inside.
However, creating an exception with another exception nested inside (i.e. doing literally what your first example does) is not a good idea. The main reason for wrapping an exception inside another exception, as opposed to providing an unrelated exception, is to retain the place where the exception has been thrown. However, your nested exception is never thrown, so it has no useful context embedded inside it.
Lets say your program is going to do a variety of math computations and want to know the available exceptions that are possible to capture to see if any are applicable.
Or, the program will be doing a lot of file i/o and other things and you want to capture specific exceptions instead of simply capturing Exception.
Maybe you may want to know if one application is even applicable in the scenario being coded.
What is the recommended way to go about researching what exceptions are available to be captured when generating code to do specific activity?
Using a IDE like Intellij or Eclipse will let you know most of the exceptions that the library code you are using throws, depending on it's javadoc(Like FileNotFoundException) and majority of the times, these are the exceptions that you should worry about.
Other exceptions like divide by zero, null pointer exception will certainly depend on the code you are writing. For example if you getting an object from a different class, you might want to check if it is null before doing any operations on it. Similarly if you are dividing by something, like K/X , you should have an idea whether X is ever going to be 0 or not.
The recomended way is to look into the javadoc of that method.
Hopefully the software author of that code wrote the javadoc in the recomended way, to also list the Runtime Exceptions that a method throws.
You can usually find this information in the Docs for the method you want to use. It will tell you what exceptions it can throw in what cases. There is no general purpose "find all exceptions" technique. This is probably a good things, because if you don't know how or why an exception is created, you probably don't know enough to handle it.
You can trace through the source of the code you are calling to find all the specific exceptions. The problem with this is that the time this takes esp since it could change between different versions of software is very high.
In general you can trust the Javadoc for broad checked exceptions, but this usually won't tell you about all specific exception or all RuntimeExceptions. (Including all future exceptions)
Note: you may wish to take different actions based on the message as well as the type of exception.
For this reason I suggest you focus on the specific exceptions which you handle differently, and have a catch all IOException or similar for unexpected exception which by their nature mean you can't know how to handle them.
There are two types of exceptions, checked and unchecked. If you don't handle checked exception you will get a build failure. You can identify checked exception if you are using any IDE. But unchecked exception are bit tricky and you may need to refer the API documentation to understand what they are, because unless it's thrown you may not know that exception can occur. Again some IDEs give you hints based on your code, for example class casting, null checking.
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 :)
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.