I think the first thing we should discuss is: what is an exception. In a short definition: an exception is a notification of an execution error occurrence.
What kind of errors can occur: programming errors and system failure.
Wait! How is a programming error different from a system failure? Let me explain: A programming error is an error that could have been avoided with a little more attention, an error that can only be resolved by a programmer. Why? Because the error is his fault. I’ll give you a clear example of this: every time the NullPointerException is thrown, is because you didn’t check if the object instance was null before you use it. Isn’t it? That’s a programming error. Programming errors in java are defined as Unchecked Exceptions. Java does not obligate you to catch this kind of exceptions. Why? Cause you can avoid them by programming correctly or with more attention and discipline.
On the other hand, a system failure error is a non programming error that is stopping the system from reaching a goal. For example: we are inserting a record into a database and suddenly an SQLException is thrown by the Statement object, notifying us that the connection to the database was lost due to network problem. The connection loss is not a programming error, you couldn’t have avoided it. These kind of exceptions are denominated Checked Exceptions in Java.
Now that we agree on what exceptions are, lets get back to the headline of this post : When things go wrong, please don’t make em worst.
What was the point here?
Look, an exception is a notification of something bad. What I was trying to say is: act correctly when you receive that notification. Don’t ignore it, you will make it worst. But what do I mean by “don’t ignore it”? To be more specific, first: never have empty catch blocks like that one on the cover picture of this post.
When you catch an exception, you are supposed to do something about it and not just hide it. Why? “Why do I have to do something about it?”. I can hear you. Let me make it clear for you once and for all:
- An exception is an indication of a bad thing
- Bad things should not happen repeatedly on reliable systems
- We have to avoid the occurrence of bad things, reduce them.
- To reduce the occurrence of bad things we have first to know that they happened.
I will repeat the number 4: To reduce the occurrence of bad things we have first to know that they happened. If you wrap your exceptions in an empty catch block, you will never know they happened and you will never ever have a reliable system. You have to let the others know. It should not be something you keep in secret. If you don’t want to do something about it, just don’t catch it, make you method throw it or re-throw it inside your catch block (usually a bad practice).
What is the best way of letting the people know that something bad happened (an exception was thrown)?
A log file. Logging the errors makes it easier for anyone to know that something bad happened. Why a log file? Why don’t I just call the ex.printStackTrace()? Printing the stack trace on your console will show the error to you while you still programming and running tests, but what if someone comes and closes the console or the console just quits? What if you want to run your application on a remote server? How will you be able to detect the bad things without the console? A log file is your best shot. You might not use a file, use a database, anything, just log it.
Wait MJ. You want me to log every single exception I catch? I say: Log every exception that will help you improve your system or detect an anomaly. Don’t log exceptions because I told you to. Log them after understanding the value it will add.
Log and keep quiet?
Remember that exception are thrown by methods. If a method catches an exception that it finds interesting to log, then it logs it. It doesn’t mean you log it and keep quiet. Tell the method that called your method that something went wrong: re-throw the exception or wrap it in another.
I keep saying “Wrap it” or “Re-throw” and you might be asking yourself what the hell each of that things mean? Wrapping an exception means to create an exception of another type, set the current exception as its cause and them throw it . Why would you wrap an exception? For abstraction and separation of concerns. If for example you have a DAO class that inserts records into a database using JDBC: your DAO methods should not throw the SQLException, they should throw a different kind of exception. Why? Because one day your DAO can stop using JDBC, meaning it wont throw the SQLException anymore, so, You have to create your own exception type and wrap the original cause when throwing the exception. Congratulations, you just met the so called “abstraction“. Re-throwing an exception on the other hand, means to throw the same exception instance inside a catch block.
How do you create your own programming exception? you create a class that extends java.lang.RuntimeException (programmer will not be forced to catch). To create a non programming exception (programmer will be forced to catch) you create a class that extends java.lang.Exception.
How do you throw an Exception without having to create your own class?
Well, this works: you have encapsulated the original exception (as I said you should), but you have created a problem. Before I explain the problem, be AWARE THAT THIS APPROACH IS A BAD PRACTICE AND SHOULD BE AVOIDED. You method throws an Exception of type java.lang.Exception. It means that the caller of your method will catch a java.lang.Exception. If the money is not enough, the caller has to give the user a chance to change the amount, if there is another problem, the caller has to give the user a chance to try again. This raises one question: How is the caller going to distinguish the two kinds of exceptions if they are the same (java.lang.Exception)? The obvious answer here is “USING The message”. Now ask yourself how comfortable is that? Remember: you should write less and do more and keep the code clear and easy to understand. That is definitely not the best way of doing any of that.
Creating your own exception types
To solve it correctly we should create 2 classes. One class that extends java.lang.Exception, and one class that extends our new class: OperationException, NoEnoughMoneyException (extends OperationException). How do we use them?
Its looking awesome now, isn’t it? But how how is the caller supposed to distinguish the exceptions? That’s one of the reasons why we made that change, so, lets see:
Can you see how easy it was to verify the type of the exception? That’s why you should adopt that practice (Assuming you said yes :)).
Things you should take in consideration when creating your own exception classes.
- The more detailed the exception is, the more helpful it becomes. Be careful, if it becomes too much informative it might also not help and might actually not be informative (My GOD this is so paradoxal).
- Exceptions are classes, so, be free to add custom attributes
- You can set the exception message on the exception class (internally), making it possible avoiding to pass a message every time you want to throw it.
This it too much for a single POST, don’t you think? What am I thinking? Why didn’t I split this is in two or more posts? Because this is web content, meaning you can stop reading anywhere and come back to it anytime. You see? You are the problematic here. :). Just kidding.
Lets discuss one last thing before I rest in peace (its 12 AM now).
Do you remember the transferMoney method? Of course you do! Great!Imagine if one of the two parameters you receive is null. What should you do?
What Iam asking you, is how should the method react to things like this: transferMoney (null,null,-1000);
Please don’t tell me we should create a new type of a exception! Why? Because java already comes with exceptions to help us handle this kind of situations. It’s a pleasure for me to introduce you the NullPointerException and IllegalArgumentException. Please be polite “say nice to meet you”. But You already know these guys, they have been bothering you since you define yourself has a java programmer.
Lets cut to the chase, how are we supposed to use them?
If for some reason you are considering to catch these exception at the moment you call that method, please forget it. Burry that idea and burn its origin (don’t burn you head). You should do your best to never let none of this exceptions show up. How are u supposed to do that? Check if the Account objects are not null before you call the method and check if the amount is valid before you call the method. If these exceptions show up, you haven’t done your job correctly, remember, these are programming errors, the java language does not require you to catch them. These two exception types (NullPointerException and IllegalArgumentException) extend the class RuntimeException that extends Exception. Every child class of RuntimeException is an unchecked exception, meaning that you are not forced to catch it. When you call a method, you should make sure a RuntineException never shows up. When you write your own method, you should make sure a bad programmers gets them. You got me!
There is more to be told, but, I’m a human being and I appreciate my bed. It never throws an Exception.
It’s always a pleasure.
MJ







Comentários Recentes