Throwing immediately wrapped exceptions - java

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.

Related

Does it make sense to throw an exception which is always chained?

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).

What is an efficient method to map errors(exceptions) occuring in a J2EE website with suitable error messages?

I am developing a J2EE website for a mini project, and I’m puzzled about exception handling. I have defined several custom exception classes, and they’re thrown from several parts of the website, and they are captured in a custom exception handler. But, i am yet to find a good way to map the occurred Exception to an error message.
To put it simply, if an exception occurs somewhere, I have a global exception handler which captures the thrown exception ( i won't swallow it within a local catch block ), but i need an efficient mechanism by which i should be able to convert it into a suitable error message to be displayed to the end users.
Also, the custom exceptions have a tree hierarchy , which means the top of the tree will have general exceptions and the leaves of the tree would have exceptions defined for a very specific purpose.
The tree would be like
CustomException
Type1Exception
Type11Exception
Type12Exception
Type121Exception
Type122Exception
Type13Exception
Type2Exception
Type21Exception
Type211Exception
Type22Exception
Type3Exception
Type31Exception
Type32Exception
Type33Exception
Type4Exception
Type41Exception
Type411Exception
Type4111Exception
Type4112Exception
Type421Exception
Type4211Exception
Type42Exception
Each exception branch would represent exceptions occurring in specific part of the website. The tree will grow more in future, if more features are added to the website What is the best practice to map the bunch of exceptions to error messages ?
And, is using instanceOf operator and isInstance() method , to check the type of exception, a good practice (in aspects of performance ,scalability and code standards) ?
Each exception branch would represent exceptions occurring in specific
part of the website.
But what if the exception happens in a common component shared by different parts of the website?
Exceptions already tell you where they happened (that's what the stacktrace is for), you don't need to put it in the name. The name is for the reason of the exception (such as IllegalArgumentException or EOFException.
Your design is poor in many ways. You should handle exceptions where you can, either locally with a specific error message (if let's say a user wants to pick a username that's already taken) or globally with a general error message.
Edit:
There are thousands of potential error situations in an application. You can divide them into categories based on what you can do to them. Let's say you try to insert a duplicate username into the database, and an exception is thrown. You catch this and tell the user to choose a different username.
That's the least exceptional case, you might even bypass this by checking if the username exists, instead of relying on an exception.
Then you have a bit more exceptional, let's say you can't connect to the database at all. You don't know why, but you're still prepared, you tell the user that something is wrong with the database, and please try again.
Then you have the most exceptional. You're not prepared for it, you don't have a catch clause for it, it flies up to the global exception handler. All you can do is show the user a generic error message that "Something went wrong", log the error, and notify the maintenance team.
Now the way to design exceptions is based on how much information you know about what happened. You might have a DatabaseException class for all DB related errors, and a DuplicateUserException that extends it to provide more detail. Also note that a DuplicateUserException would never propagate up to a global exception handler. You'd handle it right there, showing the user the screen with the error message. The error message which you'd get from a resource bundle not with the name of the exception, but a general key, such as "exception.user.duplicate".
I think your basic mistake is thinking that you can create a single place responsible for exception handling, just based on the exception type. I suggest that you let that idea go. The global handler should only handle (mainly log) the exception when nobody else will.

How to combine logging with an exception handling chain?

Suppose I have the following code:
void foo() {
/* ... */
try {
bar(param1);
} catch (MyException e) {
/* ??? */
}
}
void bar(Object param1) throws MyException {
/* ... */
try {
baz(param2);
} catch (MyException e) {
/* ??? */
}
}
void baz(Object param2) throws MyException {
/* ... */
if (itsAllATerribleMistakeOhNo) {
/* ??? */
throw new MyException("oops, error.");
}
}
I'm wondering where and how I should be logging the error.
Where the error occurs, below, in baz(), I know exactly what operation went awry and can log that fact.
At the top I have the most general context (e.g. what's the IP of the connection during whose handling we encountered the error.)
Along the way I might have some context which isn't known either at the top or at the bottom.
Another complication is that the error at the bottom might not really be considered an error when you look at it from the top (e.g. looking up something in a database fails; maybe you weren't sure ) - so I might choose to logger.WARN() instead of logger.ERROR().
So, above I described 3 locations (bottom, top, and along the way) - but it's not just a question of where to log, but also what to throw up. At every level in the middle, you have 2x2 options:
Log/Don't log a message
Throw the original exception / wrap the exception in a new exception with the added message.
What are the best practices, or some common wisdom, regarding these complex choices?
Note: I'm not asking about error handling/exception use in general, just about the dilemmae described above.
When it comes to logging, I prefer to keep all my logging at the top at the application boundary. Usually I use an interceptor or filter to handle all logging in a general way. By this concept, I can guarantee that everything is logged once and only once.
In this case, you would log inside your foo() method or whatever the entry point to your application is (you mentioned the IP address, I suppose we are talking about a servlet container or application server).
Than, catch your own exception in the filter/interceptor and log it depending on your needs. Add a catch throwable to catch all other exceptions that you did not handle in your code and log them as an error, since obviously you missed something further down in the stack trace.
This concept requires some planning ahead. You will probably use your own ApplicationException that stores the Error Message (String) along with some severity level (probably in an Enum). You need this to choose the correct log level when you do the actual logging.
This works well for all cases and has the advantage that all logging is happening exactly once. However, there is one case where you still need logging in your code: if you can fully deal with an error somewhere in your code (that is, an exception happens and you can do something that allows you to continue working without (re)throwing an exception). Since your are not throwing an exception, nothing would be logged otherwise.
To sum it up:
Log at the topmost position in a general way, preferably using an interceptor or filter.
Wrap exceptions inside your own ApplicationExceptions and add severity plus other things of interest for logging in your application.
Some suggestions that I tend to follow:
Link for some best practices
1) Trace the exception where it occurs. As the point where the exception occurs if the class or API knows the context in which the exception occurs then tracing and providing a proper log is better. But if the API cannot handle or comment on the exact context then API should not log the event and leave it on the caller.
2) Wrapping the exceptions : When there are lot of exceptions that can be thrown and all exceptions form a similar group (SQLException) which provides single exception and lets you to extract information if needed. Otherwise there would have been an explosion of exceptions that the caller needs to handle.
3) Re-Throwing the exceptions: If the API logs the exception and user can take some actions on that then the Exception MUST be rethrown to tell the user that some error condition occured.
4) Proper cause of exception : The exception message should not be too techy for the caller to understand, the message itself should guide the user to understand the underlying reason for the exception.
UPDATE:
Exception Management in Java
When I throw Exceptions in my code, I do not usually log anything. The exception is information enough.
The only exception to this is, when I am at the border of my system, that is, when the exception will leave the boundary of my system, then I log as I am not sure what the other system will do with the error.
When I handle exceptions, I log them when I actively handle them, that means when I am in a catch clause which does something more then just rethrowing the exception.
Usually this is rather at the top, but this depends on the situation.
When throwing an exception at the testing stage, you should remember:
Keep the exception message as clear as possible. Stack traces can be confusing at the best of times so ensure that what you are reading, at least, makes sense to you.
Ensure that the exception is relevant to the event. If the user types in the wrong value and you throw a NullPointerException, your code is illogical and loses it's value.
Ensure that it has as much information ABOUT THE EVENT as possible. That is, keep the message relevant. If a database call has gone wrong, print the connection string to the database, and the SQL query attempted. The state of every variable currently being used isn't necessary.
Don't waffle. It's tempting to type in technical jargon to make it look like you're hacking into the matrix. It doesn't help you in a stressful situation, and it certainly doesn't help anyone else using your code. Simple english words are always preferable.
Finally, NEVER IGNORE AN EXCEPTION. Always ensure you handle the exception, and you're outputting details in some way, following the rules I've stated above.

What is the purpose of wrapping a lower level exception in Java if I'm just going to throw my wrapper exception?

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.

How to handle exceptions when writing a library (not an application) - Java

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 :)

Categories