Exception handling when overridden method does not throw any exception - java

Short form: How do you throw exceptions (or do nice, clean exception handling; or at least dirtily force execution to stop) when the overridden method doesn't throw exceptions?
Context: We have a license for a piece of proprietary software that can be automated using Java "macros". A user-defined macro must be of this form:
public class MyMacro extends SoftwareMacro {
public void execute() {
// user code goes here
}
}
i.e. a class that extents SoftwareMacro and that has a method called execute that overrides the base class' execute. The contents of this overriding execute are what gets... well... executed when the macro is "played".
But the overridden execute method apparently does not throw any exceptions.
execute() in com.mycompany.mypackage.MyMacro cannot implement execute() in
somesoftware.base.SoftwareMacro
overridden method does not throw java.lang.Exception
Maybe this is naïve, but while developing I usually like to have the appropriate exception type bubble up to the top and force execution to stop, so that I can see them and go on to debug. This is apparently not an option here.
Should I resort to throwing RuntimeException instead? (since RuntimeException does not need to be specified) That feels a bit sloppy, and a "violation in spirit" of the base class method contracy.
P.S. No, I can't change the source code of the overriden execute method.

Looks like the intent is that each SoftwareMacro do all its own error handling. Use a big try around your whole execute() method if need be, but don't let any exceptions escape. Do whatever cleanup you need to do inside your execute method, and possibly print an error message for the user, if they provide a way to do that.
You should examine all the APIs they provide -- perhaps there's an error reporting facility you're supposed to use.

It all depends on what the "Macro player" does if it encounters a runtime exception, and on what you want to happen.
If it doesn't handle it at all, but you don't care, throw a RuntimeException.
If it handles them properly, throw a RuntimeException.
If it doesn't handle them properly, and you don't want it to fail miserably, then catch the exceptions that might happen in your execute method, and handle them as you feel is the best: show an error dialog box, output an error message, log some error in the logs...

"Should" implies there's a right answer, which IMO there isn't do what meets your needs.
If the system can tolerate a runtime exception, and it meets your needs, why not?
Not that you have a choice, since you can't throw a checked exception.
(Checked exceptions seem like a failed experiment to me, although I understand the motivation.)

So long as the execute code doesn't absorb the exception, it will still throw it if one is encountered. If the kind of exceptions thrown are either RuntimeException or sub-classes of RuntimeException they don't need to be explicitly declared, mostly because the compiler doesn't enforce their declaration since (as the name implies) they only happen at runtime, and cannot necessarily be predicted at compile time.
If, however, the execute method, which you've said you can't modify, absorbs the exception, and doesn't indicate that exception via a log entry, return value, or some kind of RuntimeException I think you're out of luck.
I would agree with Ernest that it appears that the intent is that the execute method do all its own exception handling.
NOTE: Overridden method signatures don't need to match exactly when it comes to the exceptions they throw - just the name, return type, and list & type of variables.

Related

Why do you need to catch "Exception" but not the Subclass "RuntimeException"?

The below picture shows that "Checked" and "Unchecked" Exceptions are subclasses of Exception. I find it confusing that you need to catch an Exception but you don't need to catch a RuntimeException, which directly inherits from Exception. Is there a reason that the devs didn't let us throw Exceptions without needing to catch them?
More specifically: Why can you ignore only RuntimeExceptions and it's children? Why wasn't there a Class introduced called CheckedException extends Exception and you only need to catch it and it's children?
The confusing part is, that you can throw everything below RuntimeException without issue, but when you move up to Exception in the hierarchy, you need to catch it at some point. This is confusing because "abstraction" normally works otherwise. The more you move up, the simpler and more meta everything gets. This is not the case here. The more you move up, the more you have to do (like, putting try/catch after reaching Exception).
If Exception was unchecked then you could implicitly cast checked exceptions to unchecked ones, which would mean that you could throw checked exceptions without catching them like:
public void f() {
Exception e = new IOException();
throw e;
}
and also with overriding methods, if you throw a more specific exception, you can add the requirement to catch the exception that wasn't in the superclass:
public void f() throws Exception {
}
...
#Override
public void f() throws IOException {
}
Suppose they designed it the other way. We have a CheckedException class, and subclasses of that need to be handled, but not other subclasses of Exception.
Now we call a method that might throw an arbitrary Exception:
public static void example() {
functionThatThrowsException();
}
Do we need to handle it? Yes, because that Exception might be a CheckedException. If we didn't need to handle it, we'd be bypassing the checked nature of checked exceptions.
A throwable type with checked descendants must be treated as checked, so checkedness naturally propagates up the inheritance hierarchy. Contrapositively, an unchecked throwable type cannot have checked descendants, so uncheckedness naturally propagates down. This makes it natural to make checkedness the default, and single out specific classes and their descendants as unchecked.
CheckedException (Which does exist) and RuntimeException both extend Exception. Because of this, if something throws a generic Exception (which is always a bad idea), there is no way to tell if the exception could be one or the other, so you have to catch it in case it's a checked one. If you think of the hierarchy in this way, it actually does get simpler the farther up you go.
You seem to have the idea that checked exceptions are more "complex" because you have to do more to work around them. This isn't too healthy a way of thinking about it. Instead, consider this: Exceptions are problems with the program itself - the code. We need to find these exceptions and handle them properly. After already having this concept of exception handling, we discover that there are some problems that we simply can't predict.
"How was I supposed to know the user would enter 'meow' when asked for an integer! I shouldn't have to code around that!" And so, NumberFormatException was born, and you don't have to catch it because it's a "logical error", not an issue caused by bad code (Although, arguably, it might be considered bad code if you don't handle this situation in some way).
In short, reverse your thinking. Exceptions are problems with the program that can be handled. There are some exceptions, however, that are unexpected and are a result of bad design more than incorrect code. Thus there is the addition of RuntimeExceptions which cannot possibly be expected to occur, but certainly can occur.
Perhaps it would help to not think of exception classes in terms of inheritance but simply disjoint sets of classes, one set is checked and other is not. You're right that there could be a CheckedException class allowing us to check only when explicitly intended.
However having the broader/generalized range checked helps in enforcing the catch or specify pattern. Having checked exception allows a reader of the code to figure out quickly that this piece of code needs special attention and enforcing their handling at compile time reducing the runtime bugs.
We can throw any kind of exception, checked or unchecked. If Exception or any super class of RuntimeException were to be set as checked exception then all the sub classes would become checked exceptions. As compiler is most likely checking if an instance of exception or a class in the throws clause derives from a class. It could easily have done that by checking for a specific package which probably would have been more appropriate as being checked or unchecked has simply nothing to do with the inheritance.

Should I declare all exceptions thrown from a method in the method signature or just the super class of the exceptions?

When I throw checked exceptions from a method should I just declare the super class of the exceptions in the method signature or all the different types? If I have the following exceptions:
private class SuperException extends Exception {
}
private class SubExceptionOne extends SuperException {
}
private class SubExceptionTwo extends SuperException {
}
Should the method signature be:
void confirmAccount() throws SubExceptionOne, SubExceptionTwo;
or
void confirmAccount() throws SuperException;
In the last method signature, how do I tell other developers what exceptions that could be thrown from the method? If the different sub types need different handling?
The interface should be as stable as possible. So probably Super. Many libraries use the "Super" strategy, because exception specs cause far more annoyance in maintainability than readability or safety they add. Even the IOException is a Super that nearly all Java library code uses instead of declaring more specific exceptions. (But when they do declare more specific exceptions, it's because the contract is that more general IOExceptions won't be thrown. Read on.)
You might list Sub1 and Sub2 if you really do want to say each of those exceptions can be thrown, but don't want to say that any derivative of Super can be thrown. Perhaps Sub1 is NumberCrunchException and your method calls crunchNumbers() and users of your method can be assured that's the only exception-ful thing your method does. In that case the specific strategy is better.
If the different sub types need different handling, then definitely declare the two different exceptions. Never expect the developer using your method to guess that you are actually throwing different types of exceptions.
If you declare two distinct exceptions, and the user knows from the Javadoc that they are actually descendents of the same class, the user may choose to catch them both with a catch (SuperException e) rather than two individual catch clauses. But it depends on the user's choice.
If you don't declare them separately, your IDE is not going to add the appropriate #Throws to your Javadoc comment. And your Javadoc will therefore only indicate that you're throwing SuperException, which will leave the user in the dark. Solving this by just putting it in the text of the comment is not a real solution. If any tool is using reflection to determine what your method throws, it will not see the individual exceptions in the array returned from Method.getExceptionTypes().
If the functionality expected of the different exceptions is more or less the same and it's just a matter of how they will appear in the logs, it may be better to just use the parent exception, with different messages.
The throws clause is there to convey useful information to the calling method about what might go wrong during invocation of this method. That means that how specific you are will depend on how much information you want to convey; and that will be application-dependent.
For instance, declaring throws Exception is almost always a bad idea: the information this conveys is just "something might go wrong", which is too vague to be useful. But whether calling classes are going to need perfectly fine-grained information in the throws clause is something you need to decide by looking at your program. There's no set answer.

Programmatically distinguish exceptions

The type of an exception is often enough to handle it properly (for example you try to open a file and get a FileNotFoundException). However there are cases where you might catch multiple exception of the same type. For example, an IllegalArgumentException that can be caused by more than one argument. The IllegalArgumentException does not add any additional methods (or public fields) to the Throwable interface (accoding to the online javadoc) which means that the only information that you can rely on are the nested exception (which may or may not exist) and the message (which is for human consumption).
I don't like the idea of extending IllegalArgumentException to add structured information to it, because other people would have to learn the new class. And I don't like the idea of littering projects with very specific exception classes.
Using the message field is also a bad idea because it's not meant for programmatic access.
I think IllegalArgumentException should have included details such as the class function and argument(s) in question. And in general custom exceptions should provide additional detail (other then just their type) for a more fine grained exception handling.
What are considered generally the best practices for designing exception classes, and handling exceptions of the same type?
As a general rule, I think it is ideal to have one class of exception per "type of action a caller might reasonably want to take". Of course, for one's own custom exceptions there could be a boolean or enum field providing some extra disambiguation, rather than creating trivial subclasses.
In your specific case I'm not convinced that trying to handle the exception is a good idea. RuntimeException and its subclasses usually represent coding issues, and the same is true of IllegalArgumentException. If the argument is illegal it shouldn't be passed in in the first place.
If you're in a situation where you're not sure if an argument is valid (maybe it's user input, or maybe you don't know the specific object you're calling the method on) then a better approach would be to have some way of checking the validity of the argument before passing it. Rather than say "do this" and catch the exception, ask "can I do this?" before calling.
Exception classes should be designed so as to provide all that is needed when they are caught. Note that try/catch statements are actually a form of type switch, so in general it is cleaner to create additional exception classes rather than confuse program logic by nesting too many if's within catch clauses.
It has to be said that catch clauses are not very convenient if you want to organize your error handling code in an object oriented fashion, so there are different trade offs to keep in mind.
Note that standard exception classes do have information available on what piece of code caused the exception, even though I would not advise you to base on it your error handling logic.
If the current exception was thrown in a catch clause for a different exception this should be available with the getCause() method, while the getStackTrace() should provide access to the stack of calls that were active when your exception was thrown.
Again I don't advise you to use this information except for debugging purposes.
Its true that the predefined exception classes are very general. But if you want more specific details about the exceptions then you should go for user defined exceptions. you should create your own exception classes with any level of details!
here is the pseudo code:
public class TooManyArguments extends exception{
public String toString(){
return ("..whatever information you want to give for this exception..")'
}
}
and whenever you encounter exceptional situation throw an instance of this class
throw new TooManyArguments();

how to uncatch the caught exceptions

I want to my java script to throw if there is any exception. Problem is, we are extending a super class in my script but in that super class there is an exception caught called ScriptFailureException and super class is in a JAR that we cannot edit. We want to stop that exception from being caught. Is it possible to prevent that exception from being caught or is there any other method to make our script fail in this situation. I tried System.Exit(), etc. methods but they are not working. We are running our script through TestNG.
First of all, Java is not a scripting language and has no notion of a script. You should not use the term script, but the terms "class", "method", "program".
To answer your question, if a method catches an exception, then the exception is caught, and you can't do anything about it. You might throw another exception type which would not be caught by the superclass method, though.
No unless the super class lets you know that a ScriptFailureException occured by an other way than throwing it. One of this other way can be for example a null returned value for a method call.
What actions does the Jar code take when it catches the exception? Can you detect that action after the event? For instance, if the Jar code writes to a log then you could examine the log to see if that exception is recorded there and then throw a new exception of your own.
You can make your Java fail totally by throwing an Error.
throw new Error("Oh dear");
That's messy though.
Try defining your own Exception and throwing that.
public class CustomException extends Exception { }
// somewhere else
throw new CustomException("Some detail");
A little trick is declare ScriptFailureException as an extension of RuntimeException
I think that this isn't the best way to do code, but it works. The RuntimeException objects don't need a explicit try/catch block.
Then, you must declare class StcriptFailureException extends RuntimeException
Regards!

rationale behind Java's exception hierarchy

I find Java's exception hierarchy confusing. Throwable is divided into Error and Exception, and RuntimeException inherits from Exception.
Error is an unchecked exception. Why doesn't Error inherit from RuntimeException then?
Exception is a checked exception. RuntimeException is an unchecked exception, yet it inherits from Exception. Doesn't this violate the Liskov-Substitution-Principle?
Wouldn't it make more sense if Throwable were divided into Exception (checked) and RuntimeException (unchecked), and Error would inherit from RuntimeExeption?
I find Java's exception hierarchy confusing. Throwable is divided into Error and Exception, and RuntimeException inherits from Exception.
A Throwable is anything that can be used to unwind the call stack. This should include some VM level fault (flagged by an Error) and something application specific (flagged by an Exception)
Error is an unchecked exception. Why doesn't Error inherit from RuntimeException then?
Simply because Errors are not Exceptions. There wouldn't be any point in actually "catching" an Error. For eg. What would you do after catching an OutOfMemoryError. Errors are meant to flag something seriously happened at the VM level which is not necessarily handle-able by the programmer
Exception is a checked exception. RuntimeException is an unchecked exception, yet it inherits from Exception. Doesn't this violate the Liskov-Substitution-Principle?
Not really. What the implementors were trying to say was that Exceptions MUST always be checked. Your code will be cleaner if all your methods declare what sort of application/library Exceptions they throw. RuntimeExceptions should only be thrown in case of more general / dynamic situations such as a NullPointerException where the developer might not have coded for the case but is a serious bug which is not exactly something mentioned in the application spec.
The design of exception handling in the two most popular object-oriented frameworks (Java and .NET) is predicated upon the notion that the question of whether to handle a particular exception should depend primarily upon its type, and that the types of exceptions one will want to catch are going to have a hierarchical class relationship. I think Java and .NET do things that way because C++ did it that way, and C++ did it that way because of a desire to avoid hard-wiring any non-primitive types hard-coded into the language. In the absence of a hard-coded type to which all exceptions may be cast, it's impossible for a catch statement to know anything about any exception type for which it is not explicitly prepared. If it will only make sense to catch exceptions one can decode, a catch statement will be able to sensibly act upon those types, and only those types, which derive from the one in the statement.
In retrospect, it probably would have been better to have the decisions of what exceptions should be acted upon and/or resolved by particular catch statements be determined by some means other than the class hierarchy. Among other things, a single attempt to invoke a method may fail because of multiple problems; if that happens, every catch which is associated with any of those problems should trigger, but only when all of the problems have been resolved should normal execution resume. Unfortunately, neither Java nor .NET has any mechanism to achieve such behavior.
With regard to the top-level layout of the hierarchy, I think there was an assumption that every kind of exception that might be thrown by a method would either always be expected by the immediate calling code or never expected by any calling code. Exceptions of the latter type were classified under Error or RuntimeException, while those of the former type were placed elsewhere. In practice, the question of whether an exception is expected by a method's caller should be independent of its place in the hierarchy or even the exception type. The fact that a method is declared as throws FooException does not mean that calling code is always going to expect that the exception could occur. It's very common for code to call a method which is declared as throwing an exception but believe that the circumstances surrounding the call are such that in practice that the particular call won't ever throw.. If the exception does occur, it should behave like an unexpected exception, even if an outer execution context is expecting to catch an exception of that type. Unfortunately, the exception handling mechanisms are what they are, and I don't expect any major overhaul.
I think that even better hierarchy is
Throwable
Exception
CheckedException
RuntimeException
Error
This hierarchy separates Exceptions and Errors (as #Paarth said) and makes it possible to catch all checked exceptions only (without runtime exceptions). But it seems that James Gosling thought different...
Error is not a subclass of Exception because it is not meant to catch (Once an error is occurred usually the program is no longer expected to function). So error should have more higher place in hierarchy as I believe.
It should not violate Liskov substitution because RuntimeException can be catched if you want, but only it's not enforced.

Categories

Resources