I would like to ask a code style question around Java Exceptions. I am using Java to call a C/C++ library using JNI. The convention in the library I am using is that most of the methods I can call will throw the same exception type for all errors. Let's call that a LibException. Now LibException is really a wrapper exception for a multitude of errors that can come up ranging from authentication problems, connection problems or more serious problems like corrupt input etc. LibException also contains an error code int as well as the error description string.
Even more confusingly LibException can also wrap one of my own exceptions if I throw it at the library in a callback! What I mean by that is that I sometimes provide a callback method, it is called by the library and I sometimes have to throw an exception in the callback. In that case the library picks up the exception, wraps it up in a LibException and throws it back at me in the original method call.
I would like each of the underlying problem to be handled differently. Authentication problems need to be shown to the user so he can retry, users should be notified of connection problems, but more serious problems may have to trigger my diagnostics report system (an automated mechanism that can send me parts of the logfile for debugging) and of course any exceptions I throw towards the library in the callback need to be rethrown as the original exception type.
Since I am calling different methods at multiple locations, I thought it would be a good idea to put some structure around the exception handling of LibExceptions. This is to avoid code repetition but most importantly to make sure that the different exception types are handled properly and that future me does not forget to, for example, notify the user that authentication failed.
I have tried a bunch of approaches but I am not entirely happy with the code structure I get so I would like some ideas on best practices from the community.
Static method that includes logic to sort the exceptions and throw a bunch of other exceptions
public static void handleException(LibException e) throws AuthenticationException, ConnectionException, SeriousException, MyException (MyException would be my exception that I throw in the callback)
+ve This works well in that it forces the handling of all the thrown exceptions.
+ve If a new exception type is added, the compiler would force me to handle the new exception
-ve Even though handleException() is a method that always throws an exception, the compiler (rightly) does not know this. This means that if we use handleException() in a method that has to return something, the compiler complains that a return type was missed. To make the compiler happy I have to throw another exception right after calling handleException() so the compiler understands that it will not be getting a return value because an exception is definitely thrown.
-ve I don't like the line that looks like Handler.handleException(libEx) since it's not entirely obvious that it throws a bunch of exceptions.
-ve Hard to customize the exception messages with context from the location the exception occurred (i.e. which URL we could not connect to).
A method that returns an enum with the different types of exceptions that I defined. Based on the enum I can then create the different exceptions to throw.
public static ExceptionTypeEnum Handler.
+ve Since I create the exceptions, I can now customize some error messages with extra context
-ve I could still forget to handle an enum (especially if I create a new category in the future)
-ve I still need a bunch of custom code to create the exceptions at every place I catch a LibException
Similar to #2 but instead of an enum return I could have multiple methods such as isAuthenticationException(libEx) or isConnectionProblem(libEx) and then accordingly throw the exceptions myself.
-ve I would definitely forget to handle all sections properly especially if a new exception type is added later.
The exception handler could return an exception to throw up. But since we throw a number of different exceptions the getException() method would have to return the Exception base class. This means that exception handlers would have to have prior knowledge of what exceptions could be thrown and also catch the Exception class making my exception handling more difficult.
Now in case I confused everyone with this question, I guess what I am trying to find an elegant solution to is similar to the problem described on section 'Checked exceptions inappropriately expose the implementation details' on page http://www.ibm.com/developerworks/java/library/j-jtp05254/index.html
Does the community have any other suggestions of a coding method to properly and elegantly handle these LibExceptions?
Related
I am a newbie and learning Java exceptions,
public void function (argument) {
if (condition) {
throw new Exception;
}
}
My confusion is:
If I know like the condition will cause NullPointerException, so I can throw a NullPointerException.
What if the code throw some Exceptions I didn't expect, or say I don't know what is the Exceptions of my code, what should I throw?
Like this link
When to throw an exception?
said: "Every function asks a question. If the input it is given makes that question a fallacy, then throw an exception."
but if the input does make a question a fallacy, but myself don't know this input will cause this fallacy, what should I throw?
Or I should run enough test to find all exceptions and throw them?
I know my question is weird, but if you know what am I saying, please give me some instructions. Thanks
Source: Oracle - The Java Tutorials - "What Is an Exception?":
"After a method throws an exception, the runtime system attempts to find something to handle it. The set of possible "somethings" to handle the exception is the ordered list of methods that had been called to get to the method where the error occurred.".
Each function that doesn't directly provide a means to handle an exception returns to a caller with either a successful result or an unhandled exception for the caller to handle.
A function that might encounter an exception and is able to handle it avoids the need to have the caller handle it, similarly a caller that can handle exceptions from its subroutines saves writing the handler in the subroutines.
If the caller is calling various subroutines that might all encounter the same error conditions then handling it in the caller results in less code (and consistency in the handling of the exception) over rewriting similar code in each subroutine which would be better handled by the caller.
Source: Oracle - The Java Tutorials - "Unchecked Exceptions — The Controversy":
"If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.".
Try to predict what could happen and handle it if possible, always trying to let the caller do the work if it's duplicated in multiple callees and having the 'leaves of the tree catch the light work'.
Or I should run enough test to find all exceptions and throw them?
Writing a test harness can be separated or part of the code, if it's internal then usually (but not always) you'd want to define it out of the release version.
I think an exception should be thrown:
if a function cannot satisfy an established condition
it cannot satisfy the precondition of a function it is about to call
if this can cause instability for other members
There are some other situations that can be taken into consideration, but basically for me these are the main things to keep in mind.
I am learning Java and come across the throws keyword. I came to know that it is used for exceptions we cant handle or don't wont to handle.
Why can't we just use exception.printstacktrace? Or is there any situation where throws can perform auto exception handling or it is just a mere keyword for the reader to know that the method can throw that exception?
If a method does not handle a checked exception, the method must declare it using the throws keyword. The throws keyword appears at the end of a method's signature.
You can throw an exception, either a newly instantiated one or an exception that you just caught, by using the throw keyword. Try to understand the different in throws and throw keywords.
And'throws' does not perform any exception handling it just tells to delegate exception handling to caller method as its not done in called method.
exception.printStackTrace()
or
exception.getMessage()
You can print stack trace only when exception catched. Basically java follows a rule Throw or handle with checked exceptions. Handling exception is catching them.
Also remember that some where you always have to handle your exception but you have freedom to choose where in your application flow you want to handle.
And'throws' does not perform any exception handling it just tells to delegate exception handling to caller method as its not done in called method. So that called method is aware of exception it has to handle or throw back again(but as said earlier some where it has to be handled)
PS: there is very nice question for is printstacktrace considered bad
practical usage
If you are working on enterprise applications, and any exception came in middle layers those exceptions need to propagated to controllers this is one of the practical example of throws keyword.
In such applications we write navigation logic in controller and also handle logging, so it's necessary to propagate your exception message to controller layers.
When you declare that your method throws SomeCheckedException, you require of the users of your method to handle that exception (or declare that they throw it themselves if they can't handle it). It's part of the contract of the method.
dont wanna handle? never happen, you always have to handle your exceptions. But when you throw an exception, it means that you dont wanna handle this exception in this function, and you want to deal with this in another place.
Practical Usage depends on person's requirement !
Suppose I developed an API having a method animateImages(InputStream image) Now this method will work fine if a valid image is passed but what if you pass a PDF to this method , this method fails miserably .
So if i will handle the exception , I just put a stackTrace() and log what is wrong but that is of no use for you .
I want you to know the reason and to react accordingly and send the valid Image file or whatsoever you want to do .
This is why we generally throw any Exception when we want the consumer to handle it .
I frequently come across the same problem. At the very core of my Java Application, I have methods that throw an exception which cannot be handled by any method caller. I have to bubble those exceptions up to the main method. All those exception summarize so I have many throws statements on higher levels of my Application.
E.g. I have a NodeJsManager.java class at the core of my application:
public class NodeJsManager {
public static void startNodeJs() throws ExecuteException {
// Code to start NodeJs Server goes here
}
}
To start the NodeJs Server, I have to execute something on command line. I can do that with the apache class org.apache.commons.exec.CommandLine. But it throws an ExecuteException, if the execution exited with an error code. Without NodeJs being started my application is useless. No method can catch this exception, it is just a requirement for my application to work. So the exception will bubble up almost the whole application lifecycle. I have other Managers that do the same (a ConfigurationManager that throws an exception, if the config path is wrong). All together it summarizes in many throws statements at every single method on a higher level where I don't even remember the cause of that exception.
How would you handle that problem? I must do something completely wrong because I can't find similar posts that describe my problem!
Regards
Mike
Update
I just unearthed my good old Effective Java book. The Author (a Java architect at Google) wrote the following about Exceptions:
... use checked exceptions for recoverable conditions and runtime
exceptions for programming errors.
...
If it isn't clear whether recovery is possible, you're probably better off using an unchecked exception ...
In my case it is clearly not recoverable, so throwing a runtime exception is the way to go. I always thought runtime exceptions should be prevented, this changes my point of view about exceptions in Java.
One possible approach is to deal with the Exception as close as possible to where it originated, where you have enough information to make a decision on what to do.
As you said if you have all the Exceptions caught at the highest level possible you are losing the context which is really important, because that gives information on why and how the problem occurred (and hopefully a few ways to fix it).
You said for example that your application without a NodeJS server is useless, then probably a way of doing this would be to have the NodeJSManager (if such a thing exists :D, I'm guessing) to not throw, but prevent the application from starting at all, something like
NodeJSManager nodejsManager = new NodeJSManager();
boolean succeeded = nodejsManager.tryToStart();
if (!succeeded) {
// guard, it's useless to proceed
// cleanup and exit
}
I called that method tryToStart because it can happen that the server does not start, you are dealing directly with the executables and the file system so I would say this is not so exceptional any more (but probably this is just a matter of taste).
What's important IMHO is that you specify your application start up as a series of checks, for example the node and the configuration ones, without having to deal with Exceptions to handle the flow of your code.
I don't like checked Exceptions. What I use to do (but is NOT a nice solution) is to catch the checked Exception and re-throw it as a Runtime Exception this way:
catch (ExecuteException e) {
throw new RuntimeException (e);
}
The checked Exception "e" is passed as an parameter to RuntimeException. This way, I convert a checked into an unchecked exception. But as I said, is not a nice solution and it may cause more debugging problems that it solves. When an Exception is "checked" it tends to be because the error described is "serious".
One solution would be to create your own, more general exception class that will extends Exception and wrap unhandled exceptions as causes into your own exception. This way you can at least reduce some exceptions from methods signatures. example:
Create new class StartupException or ConfigurationException and throw it with the main exception after catching it as cause during startup phase.
Moreover if you would make StartupException extends RuntimeException) you would not have to declare such exception.
Another way would be to wrap everything into RuntimeException
If abowe does not suit your needs than this is probably design flaw, (if you really cannot handle it) that you will have to deal with it.
What is the purpose of writing custom exception classes when mostly what it does is same.
For eg, NullPointerException:
class NullPointerException extends RuntimeException {
private static final long serialVersionUID = 5162710183389028792L;
public NullPointerException() {
super();
}
public NullPointerException(String s) {
super(s);
}
}
This is the basic template for most exception classes that I have seen and created.
One purpose I can think of is in handling these exception.But then cant this be based on Exception Message?. Mostly we write single handling code for each exception type. I know there are 'exceptions' to this.
But is there anything more to it? Isnt this repeating yourself where only the class name changes?
Also are there any JDK Exception classes that has some code than this?
I can think of several reasons:
Having multiple exception classes allows the programmer to be specific in their catch clauses, and only catch the exceptions they care about and know what to do with.
An exception class can carry information about the error that's caused the exception. For example, ArrayIndexOutOfBoundsException carries the offending array index, and SQL exceptions tends to carry database-specific error codes and messages.
Exception specifications -- that list exception classes -- can be used to check correctness at compile time.
Well, simply put, if you do not need special exception class, you should not make one. If you do, then you make one. There's no magic to it really.
If you're making a library, then you should of course think from the point of view of the developers using the library (even if it is just you): does your library throw exceptions for specific reasons and could the library user possibly want to catch specifically these, because they can realistically do something about it (just logging isn't reason enough, IMO).
Example with standard exception classes: Caller of a method might want to convert IndexOutOfBoundsException to null return value, while letting other exceptions to propagate normally.
If you want your custom exception to be handled in default ways, you extend right existing exception class, such as IOException. You can then catch your specific IO exception when you want to do something specific just there, but also let it be handled like any other IOException when you don't need special handling (can't do anything useful to recover).
If you have a totally custom exception which should never be caught by a superclass catch, which always should have specific catch block, then you extend Exception directly.
I think it's pretty rare to need to extend RuntimeException, because if it an exception meant to be caught it should be Exception subclass, and if it's meant to end the program or just generate log output, then it should be covered by default RuntimeException implementations with custom message string.
You need to have your client code know what exact exception happens by which part of code. so you need to let exception semantic and distinguished from other code block.
How to do this:
Define new exception class, so the class name tells what happens
Define a unifed/generic exception class which wraps code, message or other info. the code can tells what happens.
To summarize it, Do something let your exception have some meaning/semantics, and let its client know what exactly happens.
We will have a freedom to add few more methods into our Exception class which helps the client like rootCauseOfException(),description(),solution(),suggestions() etc.
Can refer below link:
https://stackoverflow.com/a/22698673
If your project has interdependent modules then you can maintain exception hierarchy also in the same dependency hierarchy so that if you catch single Exception in base layer then all the interdependent modules exceptions will be caught.
You can also mask some sensitive data like ip ,port etc before sending to client side. If custom exceptions are not used then some sensitive data can may get leaked to slient.
You can provide your own exception message which can be easily understandable by client rather than java's exception message sometimes which may be hard to understand .
It is basically to Handle different Exception in different ways. Say, you might want to do some different operation on ArrayIndexOutOfBoundsException than a NumberFormatException.
or more clearly
}catch (ArrayIndexOutOfBoundsException ex){
//operation 1
}catch (NumberFormatException ex){
//operation 2
}
The main purpose would be identify the custom / app-specific errors. You can also provide some additional methods there. For eg, we have custom exceptions that return custom messages, and also extracts cause and location from the stack trace.
I have a class XYZ whose public functions throw Exceptions.
I have been advised that all public functions exposed by XYZ should throw exceptions called XYZDataException or XYZSystemException. So even if I get other exceptions within the public methods they need to be wrapped by these XYZExceptions.
I have a couple of questions:
What is the advantage of wrapping exceptions with XYZException?
What is the advantage of differentiating between System and Data exceptions?
To me it feels right to just throw whatever exception occurs without wrapping it further.
A lot of Exception handling depends on how you plan on extending it later on. For example, if developer B came along and wanted to modify some of your code, it would be a lot easier if he understand what Exception meant what in which case. In that case, having specific Exceptions makes more sense.
As to breaking up System and Data exceptions - a Data exception would basically be something that should be non-fatal that occurs because of bad data. A System exception would be because your System failed in some way. Again, this all points to how you want to use it later on. If you want to use your code solely, and you don't care about how your exceptions come back out, then by all means, go with what is easiest at the time.
I have found that when working with other developers on a project, it is a lot easier for them to grasp what is going on when you subclass your Exceptions and throw them in specific cases.
Hope this helps!
Yes, it means they can be explicitly caught by code that knows how to handle them.
for instance, imagine you had:
class MyRecoverableException extends Exception {
...
}
You could then have code that can differentiate between them automatically, and react accordingly, such as:
try{
// ... do something ...
}catch(MyRecoverableException e) {
// Recover
}catch(Throwable t) {
// Log fatal reason, and exit gracefully.
}
Obviously how many you need is a problem to be solved by you, the application developer, but a clean separation can make all the difference when working out what went wrong, and subclassed exceptions can hold additional properties, used to pass pertinent information to handlers about the exceptional circumstances that brought them about.
Having a base type to extend from for your application/library never hurts either - if for no other reason than to allow separation of source when logging - but the exact hierarchy and complexity required beyond that depends entirely on the project. Some designs have natural and obvious choices, some require a bit more forethought (and occasionally a bit of afterthought and refactoring).
As usual, "it depends". As a general rule it does not make sense to blindly create an exception hierarchy on a per-class basis. App-specific exceptions should group exceptions in a way meaningful to that particular app, so there might be a top-level exception, then sub-classed exceptions for things like the data layer, communication layer, utilities, whatever.
The advantage is that higher levels dealing with those exceptions are not exposed to the implementation details that generate those exceptions. Also, perhaps to a lessor degree, exceptions may be grouped more meaningfully (is it relevant that it was an IOException, or is it enough to know there was a problem writing to whatever output store you're using).
Another great advantage is that app-specific information may be captured in the custom exceptions. Things like user IDs, account numbers, etc.--any application state--which must be stored as part of a string message in a "stock" exception may be assigned to a property. This may avoid random parsing issues if you actually do anything with the exceptions or try to trace through a particular event stream.
According to msdn:
To wrap an exception, you specify it as the inner exception of a new exception and then throw the new exception. This practice should be used only in situations where the original exception is not meaningful to the person who receives the exception, or the call stack for the exception is misleading or uninteresting.
Suppose method M1 is documented as throwing an exception of type X when some condition occurs. M1 calls method M2, which happens to throw an exception of type X which M1 is not prepared to handle. If M1 doesn't catch the exception from M2, the caller is unlikely to figure out that the exception thrown out of M1 isn't an X thrown by M1, but is instead an X thrown by M2, and its practical meaning and implications may be very different. Having M1 throw an exception of a type which will never be thrown by M2 may avoid this issue (though there could still be trouble if M2 could call M1 on some other object).