Advanced Exception Handling in Java
Hi my name is Marcus Biel I’m a Java developer and a software craftsman since 2001. Today I would like to show you how to properly handle exceptions in Java. Most books about programming don’t really explain exception handling.
It seems like exception handling is just some nasty cleanup stuff and you would just see some auto generated exception handling code with print stack trace Because exception handling is just in the way of the real topic and, yeah, I really think that exception handling is a very important topic that only a few developers properly can do so today I would like to show you how to do it.
and yeah let’s just start. Okay Here you see I have a little class prepared for you class training it has a public process method that would call two private methods process1 and process2 just as an example.
In process1 we created a Reader and we’re trying to read from the Reader and you see there’s an unhandled Exception, a java IOException An IOException is a CheckedException. Java, unlike most other programming languages has Checked Exceptions That would mean that the compiler enforces that you have to handle the Exception or you have to at least declare it.
So what most people do then in this case they would say “Add Exception to the Method Signature” and the problem is gone as you see and then the problem still appears up here where you could just do the same thing but this doesn’t really solve the problem it just forwards the problem to your caller and this example is really a stupid small example of course just to make a point but imagine in a system with a few hundreds if not thousands classes in a hierarchy calling each other then more and more methods would contain those declarations of Checked Exceptions plus like here you have a second method throwing an InterruptedException now we could do the same and now the method signature even grows so the more methods declaring Checked Exceptions and not handling them the more methods will have longer and longer method signatures which really can be very nasty very soon so we should really not do that let’s revert it.
so what can we do instead? We surround the code with a try catch now here again you see the printStackTrace. PrintStackTrace is a bit problematic because well it collects the whole stack of course and this may use a lot of memory actually and then printing of course again uses a lot of resources so you should also prevent that.
Now it depends the best way of handling an exception of course is really doing something to help the client for example reading from a different source I don’t really have much prepared, but we could imagine we would have a database Reader I’m just simulating this here.
Let’s say readFromDatabase yeah. Now this method isn’t implemented of course we would have to implement it and I mean this might not be so object-oriented could also have reach our mechanism 13 your reader but I mean we’re not going there I just want to tell you the best option is to handle the exception and like with a retry mechanism and the best way is to handle it as early as possible.
If you cannot handle it in such a way it might also be okay to at least log the Exception so for logging you should use a logging framework and okay so we have the message in the exception which would also print the StackTrace later on error most people I see using a Logging Framework and logging an exception they would always use error but sometimes it might also be just enough to log on warn level because I would only log on error level when there’s something that the operations team can do about the – and should do about the Exception like restarting a server, a system or a database but if this problem is solved in a different way or is not so problematic for some reason warn might just also be enough so just don’t I mean the problem is people just write what they’re used to and as everyone writes error and they do just the same because they all see an error is logged as error.
But this is not necessarily true. You should think of the logging level that is really sufficient for you. Besides Checked Exceptions I mean every method call could also produce a RuntimeException so let’s also handle this in here, as an example.
As for the logging level all the same rules apply but there’s one tiny difference for Runtime Exceptions it might be better to log using the toString() method because there are some exceptions like the NullPointerException that would not contain a message and then logging the message you would just see an empty string so if you use toString() you at least would see the name of the class that was thrown like NullPointerException which might be helpful What else can we do? For Checked Exception there’s actually even another way of handling well it’s not really handling the exception but anyway because I mean first all which I haven’t explained yet why actually are there Checked Exceptions in Java? What was the original idea? Well, it turned out it was not such a smart idea.
The idea was that – having a Checked Exception would force you to handle it but this means you have to have a way of handling it but sometimes you might not have a way of handling in and then it doesn’t really make sense to have a Checked Exception.
So you might just as well wrap the Checked Exception with a RuntimeException Okay. Here I just used the generic RuntimeException you might also declare your own Exception extending RuntimeException which is probably nicer but here for little example I just want to show how to wrap Exceptions Checked Exceptions I mean.
And now the good thing is as we’re wrapping it for the compiler it’s not a Checked Exception anymore it’s a RuntimeException and a RuntimeException doesn’t have to be handled. So now it’s perfectly fine that you throw this Exception it does not have to be handled in here either and you can propagate this all the way up and then you would have just one final catch block that would log all RuntimeExceptions or handle all Runtime Exceptions in some generic way and yeah one more really evil thing that I’ve seen quite often actually which you should please never ever do, don’t do this at home and especially not at work.
Log and rethrow. It’s really problematic for various reasons one is logging the exception here throwing it again will probably also log the Exception or handle it in some way and this duplicates usually logging messages so this can really clutter your log Uhm Monitoring is really important seeing when which Exception happens for what reason and so being able to handle it and to fix, like if there is a bug, fix the bug.
So for monitoring you should also have an exact statistics of which exception happens how many times and logging one Exception twice probably even more if you do this in a hierarchy more often. I’ve seen systems where one simple Exception was easily logged 10 times in the hierarchy.
So this really clutters your log – don’t do it. Thank you! and then also about logging one more thing as imagine we have some – usually you would have some parameters parameter 1, ah sorry and now I use an object ah no I call it parameter 2 what you should usually do is if possible don’t log just the generic message either in front but probably even better in the back – log the values of your parameters that brought you to that Exception this will really be helpful when you try to find the reason for an Exception and for objects it’s really helpful if you always for your own objects implement / override the toString() method.
Doing this will allow you to log the whole object in the case of an error. Okay. I mean, not perfect yet, actually not even correct yet but I hope you get the idea the reason why I put the parameters to the back is for filtering this will probably this message would probably appear a few times while the value of the parameters would probably be very specific for each object differently so for filtering it makes it more easy if the generic party is in the front to the left side.
well we’re talking about logging I mean this is not Exception Handling but I might just as well also add some words about logging in general I also see many people logging a lot of stuff on debug level this should be really prevented we have a debugger if you don’t know how to use it – learn how to use it debugging – especially lots of debugging can easily slow down your performance so one reason why debugging would be okayish for example if you have a QA team, an external QA team that wants to check if the methods are called so if that is a necessity in your team at least say if LOG.
isDebugEnabled() because well in my small example I just have an empty String which would be simple but usually it’s not so simple and you have lots of parameters even toString() methods called and the object could easily consist of other objects in a hierarchy so calling a toString() method can compute a lot of stuff and so in here it’s not problematic because when an exception happens we’re already are facing a problem I mean I would expect that your system that this is really an exceptional case and not the main case.
but in here this would always be used whenever debug is enabled so this is a bit different cases so first of all don’t enable debug on production probably and if you have that LOG.isDebugEnabled than this code doesn’t have to be executed in here.
Some people even would not have even a single debug but even like “entering method” and “leaving method” and that no no no – this is really ugly! Please don’t do that use your debugger.
Last but not least there is also an “info level” – you could say isInfoEnabled() but this really depends because it depends on how you production settings are set usually on production you might have info log level as default and if its default anyway than you can just as well go without checking if it’s enabled if we know it’s enabled anyway.
But then use logging info also sparsely. The operations team would probably like it to see some messages popping up if an important server or system is starting. But I would really only do it in big starting up processes and not in small methods that are called constantly.
Yeah. Okay. So much from my site so far. I hope you enjoyed my little video you can send me an email to [email protected] And see you next time! Bye!