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.
Related
I have junit tests that are using #Test(expected=) syntax.
When I run those tests the exceptions are generated and the tests pass, but the exceptions' stack trace is still logged in the console.
This is confusing because there is no indication of which test generated what message.
I have a lot of test and I don't know if those stack traces are just the expected exceptions or there is some problem in the test.
Is there a way to prevent tests that expect exceptions to be thrown from logging if the test succeeds?
Yes. Don't log them. It's not JUnit printing that stuff. It's you, in your own (non-test) code. JUnit can't magically dive in there, figure out that you wrote code that explicitly tells the VM to print the trace for no good reason, and somehow suppress that.
It's not your fault, it's.. a ton of tutorials and even here on SO, answers, as well as crazy IDE defaults that led you down this path.
So, fix it! It's not too difficult; fire up your IDE's global search tool and go hunt for e.printStackTrace(). Eliminate them all. It's hunting season.
So, how would you do this? A few steps:
First things first: Enter your IDE settings and fix the template when using the quick-fix of 'add try/catch'. The catch block should be throw new RuntimeException("uncaught", e);, not e.printStackTrace().
Any time a method's nature inherently implies that it throws a certain checked exception, make it do so. A method named openFile that does not throws IOException is just badly written. Make it throws that, then eliminate the try/catch(Exception e) {e.printStackTrace();} which we shall henceforth name 'the dodo pattern'. That should get rid of about half of them.
Next up are places where the checked exceptions you 'fixed' with the dodo pattern are not inherently part of a method's nature. For example, let's say you wrote a game save system and your current implementation works by writing it out to a DB, and you dodo-patterned the SQLException. Save games do not inherently imply DB interactions, so writing public void saveGame() throws SQLException isn't necessarily good design. The solution in pretty much all such caes is to rewrap the exception into something else. For example, make a SaveException class. Ensure it has the constructor that takes a message and a cause. Then:
} catch (SQLException e) {
throw new SaveException("Cannot save game", e);
}
Keep the message short, sweet, don't add superfluous info (If your message involves "Something went wrong" - you're doing it wrong. It's an exception that ended up uncaught. That something is wrong is implied, no need to say it). and definitely don't add exclamation marks.
Sometimes you don't need to make an exception and can rewrap into something more useful.
That leaves checked exceptions that you nevertheless doubt can actually ever really occur. Rewrap those too, into RuntimeException or some other simplistic thing, or use lombok's #SneakyThrows for these.
That should let you get rid of each and every one of those pesky .printStackTrace() calls. Once you've done that, your problem will go away.
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.
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.
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 :)
i would like to handle my exceptions in a way to warning the user about the errors that occured .
What i know is something like:
servlet.java
private void registerUser(...){
...
try{
DAOUser daoUser = new DAOUser();
daoUser.insert(user);
catch(HibernateException he){
...
}
DAOUser.java
public void insert(User user) throws HibernateException {
...
}
This is the best approach ? If not, what would you suggest ?
Best regards,
Valter Henrique.
An exception can be handled in different ways. In this case, it seems that the exception is resulting in a user notification or an error message.
Now, the example you have shown should not throw any exception of that sort, where you need to notify user. First, validate user input; second, don't make the flow of your program using exceptions.
Well, there are exceptions where we need to notify the user with some message. That can be done in controller, typically, using messages stored in property files.
You must know where to catch exception, where to throw it, and where to log. Here first thing I would like to suggest is not to do both, throw and log. If you think logging is appropriate, don't throw it. If you think throwing is appropriate, then don't log it. When you follow this way, you will automatically know which one you need to log and which one to throw. That doesn't mean some exceptions would go away without logging. The method, which doesn't throw that further, holds the responsibility to log that exception.
Another thing is to know where to use checked exception and where to use runtime. The methods which throw runtime exceptions are somewhat easier to use, per se. But that doesn't essentially mean that you should always use runtime exceptions.
I hope you are getting my points.
Well the better way would be
First Isolate Service/DAO/Controller/View layers.
Throw exception from service , handle it in controller and act it accordingly.
Our servlet wiki page demonstrated error message stuff nicely