I am creating a basic math parser with Java and doing this is revealing my shallow understanding of Java exception handling.
when I have this input:
String mathExpression = "(3+5";
and I subsequently call:
throw new MissingRightParenException();
the IDE forces me to surround with a try/catch like so:
try {
throw new MissingRightParenException();
} catch (MissingRightParenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
however, in order to force this to be a fatal exception, it looks like I have to add my own code to call System.exit(), like so:
try {
throw new MissingRightParenException();
} catch (MissingRightParenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(0);
}
I am not sure I understand the syntax behind all of this, especially why I have to use a try/catch block around throwing an exception.
what is the rhyme and reason behind this?
Instead of throwing the exception, I could do this instead:
new MissingRightParenException();
instead of calling
throw new MissingRightParenException();
so I guess my question is - if this is a fatal exception, what is the best way to make it truly fatal while giving the user the best feedback?
If you want to have a checked exception that you have to catch - but not right away - then you can define throws MissingRightParenException in the signature of your methods.
class MissingRightParenException extends CalculationException {
...
}
class CalculationException extends Exception {
...
}
class MyClass {
int myMathRelatedMethod(String calculation) throws CalculationException {
...
if (somethingWrong) {
throw new MissingRightParenException("Missing right paren for left paren at location: " + location);
}
...
}
public static void main(String ... args) {
...
try {
myMathRelatedMethod(args[0]);
} catch (CalculationException e) {
// stack trace not needed maybe
System.err.println(e.getMessage());
}
...
}
}
You can also define it as the cause of a RuntimeException but that doesn't seem a good match for your current problem.
try {
...
throw new MissingRightParenException();
...
} catch (MissingRightParenException e) {
// IllegalStateException extends (IS_A) RuntimeException
throw new IllegalStateException("This should never happen", e);
}
If your MissingRightParenException class extends RuntimeException then you don't have to catch it. The message will fall through all methods where it (or it's parent classes such as Throwable, Exception and RuntimeException) is not explicitly caught. You should however not use RuntimeExceptions for input related errors.
Usually the user will get the stack trace or at least the error message, although that depends of course or the error handling further down the line. Note that even main does not have to handle exceptions. You can just specify throws Exception for the main method to let the console receive the stack traces.
So in the end: use throws in the signature of your methods instead of catching exceptions before you want to handle them.
Assuming that your exception is currently a subclass of Exception, which is a Checked Exception, you need to handle in a try catch. If you can make your exception a RunTimeException, you no longer need to do the try-catch stuffs.
what is the best way to make it truly fatal while giving the user the
best feedback?
Personally, I don't think a missing parenthesis should be a Fatal exception. The user should have the possibility to re-try.
However, if you really want to know, It is not possible with java to create a custom fatal exception as fatal exception means something went wrong on the system/jvm, not on the program itself. Still, you should change System.exit(0) to System.exit(1) or anything not equal to 0 as a program exiting with 0 as error code mean everything went right which is not the definition of an exception.
I am not sure I understand the syntax behind all of this
Basically what you do here is throw an exception so you have two choices, either catch it or re-throw it but anyway it will have to be caught somewhere. Then in the catch you simply end the program returning an error code meaning that something failed System.exit(1)
See this Difference in System. exit(0) , System.exit(-1), System.exit(1 ) in Java for a better understanding of error code.
If MissingRightParenException is a checked exception (that seems to be the case, otherwise your IDE wouldn't be "nagging") then either you have to wrap it inside a try ... catch block or declare it via a throws clause in the method definition. The latter allows you to "bubble up" the exception and catch in the caller of your method throwing the MissingRightParenException exception.
Did you think about a throws clause?
Related
I've a question about catching an exception in method that use another method that can throw an exception.
public void methodA(File file) {
try {
}
catch (IOException ex) {
}
}
public void methodB() {
// do something with the file
File file = new File("/example.txt");
methodA(file);
}
Do I need to create a try and catch block inside the methodB? Or it's enough to catch the exception in that case IOException inside methodA?
It depends on what you'd like to achieve.
In your code sample, methodA will handle an exception and continue a methodB execution with no interrupts. This is probably not what you'd like since there was an error reading file and it should be gracefully handled.
Most likely you'd like to bubble your exception up the execution chain and handle it in a relevant object (eg. some error handler that can output error message to an user) .
Bubble up your exception like this:
public void methodA(File file) throws CustomUserInputException {
try {
}
catch (IOException ex) {
throw new CustomUserInputException(ex, "Error opening file" + file.getPath());
}
}
and then handle it in an approptiate object like this:
public void methodB() {
// do something with the file
File file = new File("/example.txt");
try {
methodA(file);
}
catch (CustomUserInputException ex) {
showErrorToAnUser();
stopStandardProgramExecution();
}
}
No, in this case you do not need to in methodB - but you might want to, because methodA might throw other errors beside IOException.
It depends on your intention and the type of exception - if your methodA throws a checked exception methodB has to either catch it or declare that it throws that exception. If its an RuntimeException, methodB might catch it or ignore it.
In most techstacks, checked exception are rare, most think they are a failed experiment.
Lastly, whether a method needs to catch exception or not depends - can methodB conceivably handle the error? If so, catch it there - if not, let it bubble up, e.g. to a general error handler or even crash the program. nothing is more annoying than a program which catches every error and does the wrong thing.
You can't since the exception can only move up the callstack. If the program also ran methods following the exception, whats the point of even creating an exception in the first place?
Try to handle exceptions where they occour. If there is a possibility of an exception when creating a File, it should be handled where the file is created. Otherwise the overhead of making sure that incoming values are not exceptions would be way too high.
I would suggest either catching it inside methodBor passing the file name into methodA and have it create the File and catch any exceptions.
What is the point of catching and then also throwing an Exception like below? Is it bad practice to do both?
try{
//something
} catch (Exception e){
throw new RuntimeException("reason for exception");
}
Usually, such code is used to re-wrap exceptions, that means transforming the type of the exception. Typically, you do this when you are limited in what exceptions are allowed out of your method, but internally other types of exceptions can happen. For example:
class MyServiceImplementaiton implements MyService {
void myService() throws MyServiceException { // cannot change the throws clause here
try {
.... // Do something
} catch(IOException e) {
// re-wrap the received IOException as MyServiceException
throw new MyServiceException(e);
}
}
}
This idiom enables to keep propagating exceptions to the caller, while conforming to the throws clause in the interface and hide the details of the internals (the fact that IOExceptions can happen).
In practice, this is always better than just calling e.printStackTrace() which will actually "swallow" the error condition and let the rest of the program run as if nothing had happened. In this respect, behaviour of Eclipse is quite bad as it tends to auto-write such bad-practice constructs if the developer is not careful.
This is called rethrowing an exception, and it is a common pattern.
It allows you to change the class of the exception (such as in this case), or to add more information (also the case here, as long as that error string is meaningful).
It is often a good idea to attach the original exception:
throw new RuntimeException("cause of the problem", e);
Rethrowing as an unchecked exception (a RuntimeException) is sometimes necessary when you still want to throw an exception, but the API of your method does not allow a checked exception.
In your example, an Exception is caught and a RuntimeException is thrown, which effectively replaces a (potentially) checked exception with an unchecked exception that doesn't have to be handled by the caller, nor declared by the throwing method in a throws clause.
Some examples :
This code passes compilation :
public void SomeMethod ()
{
try {
//something
} catch (Exception e){
throw new RuntimeException("reason for exception");
}
}
This code doesn't pass compilation (assuming "something" may throw a checked exception) :
public void SomeMethod ()
{
//something
}
An alternative to catching the Exception and throwing an unchecked exception (i.e. RuntimeException) is to add a throws clause :
public void SomeMethod () throws Exception
{
//something
}
This is one use case of catching one type of exception and throwing another. Another use case is to catch one type of exception and throw another type of checked exception (that your method declares in its throws clause). It is sometimes done in order to group multiple exceptions that may be thrown inside a method, and only throw one type of exception to the caller of the method (which makes it easier for them to write the exception handling code, and makes sense if all those exceptions should be handled in the same manner).
public void backendExecute(Map appParams, BackendTaskMetaData metaData) throws Throwable {
try {
PeriodicTaskData ptd = (PeriodicTaskData) appParams.get(PeriodicTaskData.PARAM_KEY);
String bizKey = ptd.getBusinessKey();
} catch (Exception e) {
LogServices.app.error("RPTPeriodicReportGenTask:"+ e.getMessage());
}
}
With regards to the method above, if object pointed to is null, would come across as NullPointerException, I want to know if this exception would be caught or thrown to the invoker method? thanks
Exception is a parent class of NullPointerException, so it will catch it and not throw it to the calling method.
As you are catching Exception class and NullPointerException is its subclass , exception will get catched not throwed.
Regard to above method, if object ptd is null, would come across nullpointexception,
Yes.
i want to know this exception would be catch or throw it to invoker method?
The exception would be caught by the handler. The handler will catch Exception and any exception that is descended from it. NullPointerException is a subclass of RuntimeException which is (in turn) a subclass of Exception. Therefore, it will be caught.
Now, if this may be just an illustrative example ... but it is a bad idea to:
declare a method as throws Throwable, or
catch Exception ... unless you are about to terminate the application.
Declaring a method as throwing Throwable makes it next to impossible for the caller to know what exceptions could be thrown. Instead, the compiler will insist that the caller catches ... or propagates Throwable.
Catching Exception has the problem that you will catch every subtype of Exception ... including various unchecked exceptions that 1) you are not expecting, and 2) are probably symptoms of bugs that you cannot safely recover from.
NullPointerException is a subclass of Exception and thus will be catched, however it is recommended that you don't try and catch runtime exceptions. It is better to avoid them.
For example a null pointer could be avoided by doing the following:
if(ptd != null) {
ptd.getBusinessKey();
} else {
//Notify the user in some way or do something else.
}
catch (Exception e)
means that this will catch any exception (i.e. any subclass of Exception) thrown inside the preceding try block - which, yes, includes NullPointerException. Note that this is generally considered a bad practice, as you almost always will want to handle different sorts of exceptions in different ways, hence the need for multiple catch statements.
For instance, consider a method that could potentially throw an IllegalAccessException at compile time or a NullPointerException at runtime - it's difficult to imagine a situation where you'd want to handle them the same way, so you'll typically want to do something like this:
try {
PeriodicTaskData ptd = (PeriodicTaskData) appParams.get(PeriodicTaskData.PARAM_KEY);
String bizKey = ptd.getBusinessKey();
} catch (NullPointerException e) {
//do something
} catch (IllegalAccessException e) { //for example...
//do something different
}
I have written a music player in Java, but I have a problem with finding an exception to throw. Basically, what I want the exception handler to throw is if a filename of a song stored in the playlist is altered or if the file is deleted, as naturally, in that case it won't play. I first thought it was an IOException I would need, but it gave me the error saying
exception IOException is never thrown in body of corresponding try statement
Now, I understand that that means that I'm working with the wrong Exception class, and so I tried to write my own that extends Exception, but it gives me the same error when I try to compile. Can anyone see what I'm doing wrong?
This is the method as it is right now:
public void play() throws NoMatchException
{
if(player != null) {
player.stop();
}
try{
int fileToPlay = tracklist.getSelectedIndex();
String filename = organizer.getFile(fileToPlay);
Media song = new Media(filename);
player = new MediaPlayer(song);
setVolume(currentVolume);
player.play();
player.setOnEndOfMedia(new Runnable() {
#Override public void run() { next(); }
});
}
catch (NoMatchException e){
//Some exception
}
}
When you are not sure what exception you need to catch, go to the documentation of the corresponding method. It turns out that the constructor of Media would throw MediaException - this is the exception that you need to catch. Scroll down to the "throws" section, and look for the exceptions that do not extend RuntimeException (runtime exceptions usually indicate programming errors; the need to catch this is rare).
When you are deciding to catch an exception at a particular level of your program, see if your code can do something meaningful about it. You shouldn't be catching exceptions unless you know what to do when to catch them.
This code makes no sense.
Your catch block is empty and does nothing. Your method says it throws a NoMatchException. Why don't you eliminate the try/catch and let it do so?
You catch exceptions when you have a viable strategy for recovering. Doing nothing is not a strategy. Just let it bubble up and let the caller deal with it.
If you do have a viable recovery strategy, implement it in the catch block and remove the throws clause from the method signature. Either one or the other, but not both.
I'd like to catch an exception, log it, set a flag, and the rethrow the same exception
I have this code:
public Boolean doJobWithResult() {
boolean result = true;
final Feed feed = Feed.findById(feedId);
try {
feed.fetchContents();
} catch (Exception ex) {
result = false;
Logger.info("fetching feed(%d) failed", feedId);
throw ex;
}
return result;
}
But eclipse complains at throw ex, telling that "Unhandled exception type Exception", and suggests me to add a try-catch block around it.
In fact, I want the process calling this method to handle the exception, and not handle it myself... I just want to return true if everything goes ok, and log it if there's an exception
On the other hand, I can wrap the exception inside another exception, but I can't throw the same one..
any idea?
I think there are various things to mention here:
You either want doJobWithResult() to return true on success and false on failure, or return nothing on success and throw an exception on failure.
Both at the same time is not possible. In the first case, catch the Exception, log it and return false, in the second case change your signature to return void and throw an exception and handle it in the caller.
It's a Don't to catch an exception, log it and rethrow it. Why? Because a potential caller of your method does not know that you are already logging it, and migh log it as well.
Either throw an exception (in which case the caller has to deal with it) or catch it and handle it (log it).
Note that throwing Exception does not give the caller of your method any clue about what might potentially go wrong in your method, it's always better to throw more specific exceptions, or to wrap an exception in a user-defined one and rethrow it.
Moreover, if you throw Exception, a caller might be tempted to catch Exception without noticing that this will also catch every RuntimeException (since its derived from Exception), which might not be desired behavior.
Your doJobWithResult method needs to declare that it can throw Exception:
public Boolean doJobWithResult() {
becomes
public Boolean doJobWithResult() throws Exception {
You can throw the same exception if you add throws Exception to your method signature.
Otherwise you can throw a RuntimeException.
public Boolean doJobWithResult() {
boolean result = true;
final Feed feed = Feed.findById(feedId);
try {
feed.fetchContents();
} catch (Exception ex) {
result = false;
Logger.info("fetching feed(%d) failed", feedId);
throw new RuntimeException(ex);
}
return result;
}
In such a case, you won't need to indicate that public Boolean doJobWithResult() throws something but make sure you handle it properly later on (catch or expect your thread to stop... it's a RuntimeException afterall).
Since Exception is checked, an alternative to catching the Exception is to declare your method as throwing it:
public Boolean doJobWithResult() throws Exception {
// ...
}
If doJobWithResult doesn't have to handle the exception, then remove the catch block and add "throws Exception" to the method signature. The exception logging can be done in the class/method that have to deal with the Exception in a corresponding try/catch block.
There is no need to set the result as false in the catch block, as the value won't be returned(as we are throwing an exception).
Your method should also declare that it throws an exception and so the client will be forced to handle it.
Also consider using a more specific exception which will be thrown in this particular case.
Add throws Exception to your method. You also don't need to add result = false; in your catch block.
I think the way you handle this exception is really appropriate if any failure of feed.fetchContents() method cannot be recovered. (Idea is better to halt rather than continuing)
Apart from that I would suggest you to use more specific exception hierarchy.
And another thing I got from effective java book is if you write such a method you must document with #throw (in comments) with the reason.
You could throw an unchecked exception
Logger.info("fetching feed(%d) failed", feedId);
throw new RuntimeException(ex);
I spent the last hour looking for it since not even the Complete Reference book mentions this explicitly: unhandled throw ThrowableInstance works only with unchecked exceptions.. And only runtime exceptions are unchecked. By unhandled I mean something like this:
class ThrowDemo {
static void demoproc() {
try {
throw new NullPointerException("demo");
} catch(NullPointerException e) {
System.out.println("Caught inside demoproc.");
throw e; // re-throw the exception
}
}
public static void main(String args[]) {
try {
demoproc();
} catch(NullPointerException e) {
System.out.println("Recaught: " + e);
}
}
}
This example is taken verbatim from the Complete Reference book (9th edition).
The first throw statement i.e throw new NullPointerException("demo"); is handled by the following catch block, but the second throw statement i.e. throw e; is unhandled by the demoproc() method. Now this works here and the above code compiles successfully because NullPointerException is a runtime/ unchecked exception. If the e instance were a checked exception or even an Exception class instance then you'd get an error saying the exception e is unhandled and you'd either have to handle it within demoproc() or you'd have to explicitly declare that demoproc() throws an exception using throws in the method signature.