Proper exception handling - java

Lets say we have two classes Connector and Main. First one has method connect(); and another has actionListener() at the button. The Connector.connect() may throw an exception. I'm not sure where is the proper place to handle this; in Connector or in Main in general? If we programming android, is it the same place to put logs ?
Edit:
Great article covering above problem:
https://today.java.net/pub/a/today/2003/12/04/exceptions.html

It would be much better to throw the exception to the user level if you want the user to know about the exact exception. Otherwise if it is not that important and the exception can be recovered then you can handle it in Connector itself and return some value representing error.
If the exception being thrown from the Connector is not inline with the abstraction level of Main method, then wrap it around an exception that is inline with the caller's abstraction level.
Throw early and catch late is the general rule for exception handling.

Depends on the kind of actions of the handler. If you need to show a message to the user, handle the exception in the view layer (guess it´s Connector in your case). If you need to do actions with the database (for example, a rollbak), handle it in the persistence layer.

Related

Where should I add IOExceptions in Java? [duplicate]

I have been coding in Java for a while now. But sometimes, I don't understand when I should throw the exception and when should I catch the exception. I am working on a project in which there are lot of methods. The hierarchy is something like this-
Method A will call Method B and Method B will call some Method C and Method C will call Method D and Method E.
So currently what I am doing is- I am throwing exceptions in all the methods and catching it in Method A and then logging as an error.
But I am not sure whether this will be the right way to do it? Or should I start catching exceptions in all the Methods. So that is why this confusion started in my- When should I catch the Exception vs When should I throw the exceptions. I know it's a silly question but somehow I am struggling to understand this major concept.
Can someone give me a detailed example of When to catch the Exception vs When to throw the Exceptions so that my concepts gets cleared on this? And in my case, should I keep on throwing the exception and then catch it in the main calling Method A?
You should catch the exception when you are in the method that knows what to do.
For example, forget about how it actually works for the moment, let's say you are writing a library for opening and reading files.
So you have a class, say:
public class FileInputStream extends InputStream {
public FileInputStream(String filename) { }
}
Now, lets say the file doesn't exist. What should you do? If you're struggling to think of the answer, that's because there isn't one... the FileInputStream doesn't know what to do about that problem. So it throws it up the chain, i.e.:
public class FileInputStream extends InputStream {
public FileInputStream(String filename) throws FileNotFoundException { }
}
Now, lets say someone's using your library. They might have code that looks like this:
public class Main {
public static void main(String... args) {
String filename = "foo.txt";
try {
FileInputStream fs = new FileInputStream(filename);
// The rest of the code
} catch (FileNotFoundException e) {
System.err.println("Unable to find input file: " + filename);
System.err.println("Terminating...");
System.exit(3);
}
}
}
Here, the programmer knows what to do, so they catch the exception and handle it.
There are two cases when you should catch an exception.
1. At the lowest possible level
This is the level at which you are integrating with third party code, such as an ORM tool or any library performing IO operations (accessing resources over HTTP, reading a file, saving to the database, you name it). That is, the level at which you leave your application’s native code to interact with other components.
At this level, unexpected problems out of your control such as connection failures and locked files may occur.
You may want to handle a database connection failure by catching a TimeoutException so that you can retry after a few seconds. The same goes for an exception when accessing a file, which may be locked by a process at the moment but be available at the next instant.
The guidelines in this scenario are:
Handle only specific exceptions, such as SqlTimeoutException or IOException. Never handle a generic exception (of type Exception)
Handle it only if you have something meaningful to do about it, such as retries, triggering compensatory actions, or adding more data to the exception (e.g. context variables), and then re-throw it
Do not perform logging here
Let all other exceptions bubble up as they will be handled by the second case
2. At the highest possible level
This would be the last place where you can handle the exception before it is thrown directly to the user.
Your goal here is to log the error and forward the details to the programmers so they can identify and correct the error. Add as much information as possible, record it, and then show an apology message to the user, as there’s probably nothing they can do about it, especially if it is a bug in the software.
The guidelines in this second scenario are:
Handle the generic Exception class
Add more information from current execution context
Log the error and notify the programmers
Show an apology to the user
Work it out as soon as you can
The reasoning behind these guidelines
First, is that exceptions represent irreversible errors. They represent represent a bug in the system, a mistake made by the programmers, or a situation beyond the control of the application.
In these cases, there is usually little or nothing the user can do. Thus, the only thing you can do is log the error, take the necessary compensatory actions, and apologize to the user. If it is a mistake that the programmers made, it is best to let them know and fix it, working towards a more stable version.
Second, try catch blocks can mask application execution flow depending on how they are used. A try catch block has a similar function to that of a label and its goto companion, which causes the application execution flow to jump from one point to another.
When to throw exceptions
Easier to explain in the context of developing a library. You should throw when you reached an error and there's nothing more you can do besides letting the consumer of your APIs know about it, and letting them decide.
Imagine you're the developer of some data access library. When you reach a network error, there's nothing you can do besides throwing an exception. That's an irreversible error from a data access library standpoint.
This is different when you're developing a website. You would likely catch such exception in order to retry, but would want to throw an exception in case you received invalid parameters from outer layers since they should have been validated there.
Which is again different in a Presentation layer, where you expect the user to provide invalid parameters. In that case you just show a friendly message instead of throwing an exception.
As featured at https://roaddd.com/the-only-two-cases-when-you-should-handle-exceptions/
An exception should be thrown when a function experiences a failure, i.e., an error.
A function is a unit of work, and failures should be viewed as errors or otherwise based on their impact on functions. Within a function f, a failure is an error if and only if it prevents f from meeting any of its callee’s preconditions, achieving any of f’s own postconditions, or reestablishing any invariant that f shares responsibility for maintaining.
There are three different kinds of errors:
a condition that prevents the function from meeting a precondition (e.g., a parameter restriction) of another function that must be called;
a condition that prevents the function from establishing one of its own postconditions (e.g., producing a valid return value is a postcondition); and
a condition that prevents the function from re-establishing an invariant that it is responsible for maintaining. This is a special kind of postcondition that applies particularly to member functions. An essential postcondition of every non-private member function is that it must re-establish its class’s invariants.
Any other condition is not an error and should not be reported as an error.
Report an error wherever a function detects an error that it cannot deal with itself and that prevents it from continuing in any form of normal or intended operation.
Handle the error in the places that have sufficient knowledge to handle the error, to translate it, or to enforce boundaries defined in the error policy, such as on main or thread mainlines.
Source: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
In general, catch at the level where you can do something useful about it. For example, user is trying to connect to some database, and it fails in Method D.
How do you want to handle it? Perhaps by putting up a dialog saying "Sorry, cannot connect to SERVER/DB" or whatever. Is is method A, B, or C that created this SERVER/DB information (say, by reading a settings file or asking for user input) and tried the connection? That is probably the method that should handle the Exception. Or at least 1 away from the method that should handle it.
It really varies depending on your application, so this can only be very general advice. Most of my experience is with Swing / desktop apps, and you can usually get a feel based on which classes are doing program logic (e.g. "Controller" stuff) and who is putting up dialog boxes (e.g. "View" stuff). Usually the "controller" should catch the exception and try to do something.
In a web app this can be different.
Some very skeletal code, most of the classes do not exist, and Im not sure if a URL for the DB even makes sense, but you get the idea. Vaguely Swingish...
/* gets called by an actionListener when user clicks a menu etc... */
public URL openTheDB() {
URL urlForTheDB = MyCoolDialogUtils.getMeAURL(URL somePreviousOneToFillInTheStart);
try {
verifyDBExists(urlForTheDB);
// this may call a bunch of deep nested calls that all can throw exceptions
// let them trickle up to here
// if it succeeded, return the URL
return urlForTheDB;
}
catch (NoDBExeption ndbe) {
String message = "Sorry, the DB does not exist at " + URL;
boolean tryAgain = MyCoolDialogUtils.error(message);
if (tryAgain)
return openTheDB();
else
return null; // user said cancel...
}
catch (IOException joe) {
// maybe the network is down, aliens have landed
// create a reasonable message and show a dialog
}
}
I'll share a pattern that has saved my bacon in a production environments or two.
Motivation
My aim is to ensure that the poor dude (maybe me) who is in at midnight trying to resolve a sev1 support ticket, gets a nice hierarchy of 'caused by' errors to follow, complete with data such as ID's, all without over cluttering the code.
Method
To achieve this, I catch all checked exceptions and re-throw them as unchecked exceptions. I then use a global catch at the boundary of each of my architectural layers (usually abstracted or injected so it is only ever written once). It is at these points that I can add extra context to the error stack, or decide whether to log and ignore, or raise a custom checked exception with variables to hold any extra context. On an aside, I only log errors at the top layer to stop 'double logging' from occurring (e.g. the cron job, the spring controller for ajax)
throw new RuntimeException(checked,"Could not retrieve contact " + id);
With this approach there is no cluttering of your GUI or business tier's method signatures by having to declare 'throws' for database related exceptions.
An Example of how this works in Real Life:
Lets say my code's job is an automated process to renew many insurance policies. The architecture supports a GUI to manually trigger renewal for one policy. Lets also say that the postcode for the rating area is corrupted in the DB for one of these policies.
An example of the type of error log I would want to achieve would be.
Log message: Flagging policy 1234 for manual intervention due to error:
From Stack Trace: Error Renewing Policy 1234. Rolling back the transaction ... This catch would also cover errors such as save errors, or generation of a letter.
From Stack Trace: Caused by: Error Rating Policy 1234 ... This catch would pickup errors retrieving many other objects, and algorithm errors such as NPE etc...
From Stack Trace: Caused by: Error Retrieving Rating Area 73932 ...
From Stack Trace: Caused by: JPA: unexpected null in field 'postcode'
You should handle the exception at the lowest possible level. If method can't handle the exception properly you should throw it.
catch If you have method which connects to resource (eg opens file/network)
throw if class higher in hierarchy needs information about error
You generally throws an exception when you want to notify the caller of the method of some failures.
e.g invalid user input, database problems, network outages, absent files
As others have said, as a general rule, you should catch an exception when you can actually handle it, otherwise, just throw it.
For example, if you are writing code that reads information about a connecting player from a save file and one of your I/O methods throws an IOException, then you would want to throw that exception and the code that invoked the load method would want to catch that exception and handle it accordingly (like disconnect the player, or send a response to the client, etc.). The reason why you would not want to handle the exception in the load method is because in the method, you cannot meaningfully handle the exception, so you delegate the exception to the caller in hope that they can handle it.

The use of checked exception for errors to be dealt with in web layer

I am having a hard time organizing how I should deal with errors that occur in the service layer. The reason for throwing that exception in this method is when the password provided is to weak or the confirmation id is wrong. The name of the exception is not settled yet though.
However, are checked exceptions to be avoided in a new application anyway? If so, how do I communicate errors like this to the caller? The caller in this scenario is the web layer which exposes a web service. I want to handle the error in the web layer and create a error message.
I have a method:
boolean confirmPasswordReset(int accountId, String confirmationId, String newPassword) throws ConstraintViolation;
And this is the exception class:
public class ConstraintViolation extends Exception {
public ConstraintViolation(String message) {
super(message);
}
}
From reading this article it looks like it should be right:
http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-092345.html
Contingency
Is considered to be: A part of the design
Is expected to happen: Regularly but rarely
Who cares about it: The upstream code that invokes the method Examples: Alternative return modes
Best Mapping: A checked exception
I try to use checked exceptions as little as possible. I think using a runtime exception and documenting it clearly is enough.
From your case, you seem to be the one designing and controlling the web layer. In that case, you already know what runtime exceptions your service layer throws and how to handle them. You don't need to be told by the compiler.
I would only use a checked exception if the exception is recoverable, and the client of the code is external where I have to force it to handle the exception. Even then, the result will most likely be one more empty catch block.
Here you can find a good discussion of the pro's and con's of both approaches.
http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html
What I think is important (similiar to the author of article above) is that you choose which way to go (checked or unchecked) and then stay consistent. Otherwise you'll end up with a messy codebase and will likely suffer from the downsides of both approaches.

Making a checked exception a RuntimeException

I'm working on a legacy system that has a custom exception that's used gosh-frickity-everywhere. It was inspired by the ServletException class, that said "well any time you have an exception in your Servlet, you'll want to throw this ServletException".
As the system evolved (over 10 years) a more robust system of catching the exceptions at a higher level has taken place and it's no longer necessary to wrap every exception in this custom exception. (One could argue it never was, but that's another story. It's a stable app, so I tend not to complain too much!!) But we're not going to be refactoring them all at once, just slowly over time.
However, one thing that would make things simpler going forward would be if the custom exception were a runtime exception instead of a checked exception. This way we wouldn't need to explicitly catch it everywhere, and legacy code that hasn't been refactored yet will just continue to throw this the same way as they'd throw a null pointer exception if one occurred.
My question is... What are the side effects of taking a once checked exception and making it a runtime exception?
I can't think of any, aside from warnings for unnecessary check and throws declarations, but it would be nice to get input from someone who has been down this road before.
Changing a checked exception into an unchecked one has very little practical effect on existing, working code, but you do need to watch out for the possibility that somewhere in your code you catch (RuntimeException ...). Such catches do not intercept your custom exception now, but they would do if you make it unchecked.
You might also run into issues if you do anything reflective related to methods that throw that exception (which apparently is most of them).
Something like that happened on an old module of a app that I had to maintain. The only problem translating exceptions to runtime is that you may lose granularity but that is entirely up to you to handle.
For example, we had a ton of code like this in the deeper layers:
catch(IOException e){
Throwables.propagate(e);
}
We used that pattern carelessly all over that layer and, when we needed to check the exception cause, we always had to get the cause of the exception and that made a lot of boilerplate in higher layers. To this day I believe it's better to create a good class hierarchy of non-checked exceptions in order to preserve granularity. e.g.
catch(IOException e){
throw new FileNotCreatedException(e);
}
And with this you can catch the exception easily in other layers and divide errors and fallbacks easily:
catch(FileNotCreatedException e){
notifyError(e);
} catch(NoMoreStorageException e){
releaseSomeStorage();
retryOperation();
}
Here are a few that I can think of
Runtime exceptions could potentially go to a layer where you didnot intend it to go.
ex: a Servlet ---> Service ---> DAO. Runtime exceptions thrown by DAO related to database interactions could potentially land up on Servlet. Clear segregation of layers where each layer handles all exceptions (checked/runtime) at its entry points can ensure that this doesn't happen.
Runtime exceptions can leave system in an inconsistent state.
ex: If the sequence diagram looks like Class A --> Class B ---> Class C and if Class B1 is injected between B and C therefore Class A ---> Class B ---> Class B1 ---> Class C then neither Class A, B, B1 would know that they might have to cleanup when this runtime exception occurs in Class C. In fact this can potentially affect the semantics of any dependency injection.
As a general thumb rule in my opinion:
Use checked exceptions when you "expect" the exception as part of a normal control flow and know how to handle it. ex: Validation of a business rule say account balance has to be greater than debit amount by atleast 100.
Use unchecked exceptions when you "don't expect" the exception as part of a normal control flow hence have no means of handling it yet you know that "some class" within your "layer" would handle it to ensure graceful degradation ex: DB connection lost would have handled by your "service" layer entry class.
Never use error. Only JRE has reasons to throw errors.

Always try-catch-finally for exceptions? Central error management?

I wonder if I always have to use try-catch-error blocks that clutter the code a lot, if I want to catch an error.
Or can I somehow define a global error catcher?
Especially regarding Java EE Webapps.
For every unhandled ex I'd like to log to a specific file, and display a general error page to the user.
I thought I might achieve that with aspects. But for aspects to catch on #AfterThrowing, I too have to introduce try-catch blocks. And as there is no central class for the backing-facades, I would have to surround every backing method with trycatches.
Then the aspect would take them, but I need something to catch without explicit throws exceptions.
How could I to that?
You are looking for the declare soft construct. This will wrap the given exception in a SoftException (an AspectJ-specific RuntimeException) so that it does not need to be explicitly handled. Then you can handle all of these exceptions with some AfterThrowing advice.
declare soft only exists in code style AspectJ (ie- there is no annotation for this). So, you will need to compile your code using the AspectJ compiler, but you can still use load-time weaving for this if you like.
See here:
http://www.eclipse.org/aspectj/doc/released/progguide/quick-other.html
And here:
http://www.eclipse.org/aspectj/doc/released/adk15notebook/declare-soft.html
Here's a code snippet that shows how it can be done:
aspect ErrorHandler {
declare soft : Exception : within(*);
after() throwing(Exception e) : handler(e) {
// do something...
}
}
This will route all exceptions in your system through your custom error handler. And you won't need to explicitly catch or throw them.
It's simple and powerful. Perhaps too powerful, though. I'd recommend refining and being more precise about exactly which exceptions should be softened and which ones need to be advised, but this is the basic idea.
You don't have to do this in every method.
You should not catch an exception that you can't "handle". Handling means more than just rethrowing or logging or printing a stack trace. I think handling means implementing a meaningful recovery strategy.
It might mean "the buck stops here": You're Gandalf on the bridge at the edge of a layer boundary, and no exception shall pass. You don't want users to see nasty messages, so you catch and route them to a friend, easy to understand page that tells them what to do next.
Finally isn't always necessary, but it's perfect for cleaning up resources like file handles and database cursors.
If you cannot handle an exception, there's no shame in adding the throws clause to the method signature and letting callers figure out what they want to do.
In the general case, there is no mechanism to do this - Java does not have what you're looking for.
However, depending on your circumstances, it might be possible.
web.xml Exception Handler
The web.xml file allows you to define a URL to be used to handle specified exception type. (See, for example, http://wiki.metawerx.net/wiki/Web.xml.ExceptionType).
Since you're writing a webapp, you may be able to just let the exceptions throw all the way to the top, and then handle them this way.
Custom interceptor
You mention that you have backing-facades. Depending on how they're being constructed, you may be able to put a generic proxy in front of them to catch and handle the exceptions you're interested in. You've tagged your question with spring, to you might want to look at Spring AOP Proxies.
There might be other ways to get what you want, but it will depend on the specifics of your application's architecture.
The finer control you have of the exceptions, the easier it will be to debug/provide a meaningful message.
To which extent? I would link that to the complexity / expected lifetime of your application. The bigger those are, the finer should be your handling.
I see two main approachs:
User approach: You get at least one exception handling for each UI action (so you can say: "Do not push that button AGAIN").
Debugger approach: Every method has its control.
Keep in mind that most handling could be just logging of rethrowing of the exception.
More to the point, most probably, your Java EE framework will have log options in its configuration files (many of them working with java.util.loggin or log4j). You could tweak that; of course, what is send to each log category will depend of the framework implementation (so maybe not all ERROR messages will be Exceptions).

When would you prefer to declare an exception rather than handling it in Java?

I know we can declare the exception for our method if we want it to be handled by the calling method. This will even allow us to do stuff like write to the OutputStream without wrapping the code in try/catch block if the enclosing method throws IOException.
My question is: Can anyone provide an instance where this is usually done where you'd like the calling method to handle the exception instead of the current method?
Edit: I meant calling method instead of super class in the last line.
In general, I would say design your exception flow so that the exception is caught by the code that can actually take appropriate action.
This usually means that in a "library" method (or, some kind of general utility method in a large project), you will be throwing exceptions not catching them.
On the other hand, if you have a situation where you find yourself declaring your method to throw an exception that you believe in practice will hardly ever occur (e.g. serialisation generally involves all sorts of spurious checked exceptions which in practice won't occur, e.g. if you're deserialising an Integer, it's really unlikely that the Integer class is not present, but you still have to catch the appropriate exception), then you have a third option of re-casting to a RuntimeException.
I guess by "super class" you mean the code that called your method.
If you expect the caller to know more about the problem compared to your method, than you can pass this responsibility up the calling stack.
In general, if you do not know how to handle the problem, don't. Ether pass it or wrap it in another exception.
If you can't handle the error at the point in a sensible way (e.g. displaying error message, taking an alternative path, etcetera), then just let it bubble up.
If you want the error to be handled at a different level of the application.
Here's a semi-concrete example. Let's say I've got a web application which is implemented as a series of states and actions. Suppose that, while a state is being processed, a database access causes an SQLException to be thrown. This would not happen during the normal operation of my application; it would only happen if there were something wrong with the database.
The method that access the database doesn't need to know what my procedure for handling semi-fatal errors like this is. That logic implemented at a higher level — in the method that processes the state — and it's essentially the same for any runtime error, whether it's literally a RuntimeException or not: spit out a nice-looking error message to the user telling them to contact tech support.
Imagine if I had to add a try/catch block performing this logic to every method that accessed the database and could possibly throw an SQLException. That's what's called a nightmare.
I have used expections to as part of transferring information between architectural layers of application.
For Example:
if the DAO (Database Access Layer) gets a SQLException it throws a customized DAOLayerException which is caught by the businesslayer which in turn throws an exception which is caught by the presentation layer.
This was for unchecked exceptions.
I usually follow the practice of throwing checked unchecked exceptions (not handling them) if the function is to be used by numerous caller or are unknown at the time of development of the function.
In web frameworks (like spring) you often let errors propagate and container will deal with them (by showing error page or message to the user, rolling back transaction, etc).
Also, there are lots of java errors you never catch, like OutOfMemoryError. You can catch them, but you can't deal with them properly.
You asked for an example, and here is a common one.
If you are writing code to read a particular file format, these normally declare IOException. The reason for this is that it might be used by a desktop app (which wants to put up a dialog box) or a text utility (which wants to write an error message) or a web app (which wants to return an error code). Exception handling allows you to do that.
Yes, I would declare it so it propagates up until a parent calling method which would actually handle it (display on UI, break there, ..)
For Instance, I may have some helper methods in a sendEmail method. If a helper method say checkEmailAddress() produced an exception, I would want sendEmail to know about it, which can further propagate it up or do an alert on UI "email is wrong"

Categories

Resources