Which Exception class to use? - java

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.

Related

How to correctly catch an exception if method uses method that throws an exception

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.

Throws clause in main method

Why I need to put the throws clause in the main method to handle the exception? It shouldn't be only the try-catch supposed to handle exceptions? Sorry for my english
public static void main(String[] args) throws IOException {
createFileDude();
}
public static void createFileDude() throws IOException {
File file = new File("C:\\Users\\User\\Desktop\\Test.txt");
try {
System.out.println("Create file>> " + file.createNewFile());
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
Exception means something went wrong in the 'current method'. Now, the developer can handle it in the catch block of current method, or just tell to the calling method that something went wrong for them to handle.
Like this, eventually the developer can cascade the error back to the operating system. So, it is all about throwing the error back to the calling method or not throwing it back at some point.
In this case, there are two places where you as a developer can decide if the exception message be cascaded back to the OS or not, first is in the method you wrote. As I see you wrote that the exception be thrown, now in main method, you as a developer again have a chance to not throw it to OS (by enclosing in it try-catch but don't throw in catch block), or throw it to OS.
In your example you chose to throw it back to the OS by adding throws clause.
From Java perspective, Java wants the you (the developer) make a conscious decision on any given (checked) exception, and so you'll see compilation errors until you either suppress the exception by not throwing in, or until you actually throw it back to the OS from the 'main' method.

Fatal exception handling in Java

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?

How to fix SQLException in the Catch Statement?

This program is about auto complete. When I type something to the textfield, a list of suggestions will appear.
I make the method onWordUpdated() for a list of suggestions from the DB when I type something to the textfield.
Now, the problem is I have this error:
exception java.sql.SQLException is never thrown in body of corresponding try statement
I made a comment in the code so that you will know which line.
Could someone help me how to fix this?
thanks..
I have this code:
public void onWordUpdated(final String toComplete)
{
new Thread(new Runnable()
{
public void run()
{
try
{
final List<Suggestion> suggestions = suggestor.getSuggestions(toComplete);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
suggestionWidgetModel.clear();
for (Suggestion suggestion : suggestions)
suggestionWidgetModel.addElement(suggestion.getCaption());
if (!suggestions.isEmpty())
suggestionWidget.setSelectedIndex(0);
}
catch (SQLException e) // This line is my problem, Could someone help me how to fix this? Thanks..
{
e.printStackTrace();
}
}
});
}
catch (SQLException e1)
{
onSqlError(e1);
}
}
}, "onWordUpdated").start();
}
The compiler is simply telling you that you don't need to catch that exception at that point.
SQLException is a checked exception, which means that your code should only see it if you either explicitly throw it, or you call a method that declares it in its throws clause. Neither of these is true for the code in that particular try/catch block.
You should be able to just get rid of the inner try/catch block and probably the outer one too.
IIRC, it is theoretically possible to see checked exceptions that haven't been declared, but this unlikely to arise unless you take special steps to make it happen.
Java has two types of exceptions: unchecked (those that inherit from RuntimeException or Error) and checked (all others that inherit from Exception).
A checked exception has the following properties:
If a block of code throws one, it must be caught in a catch block or the method must declare that it may throw that type of Exception.
If some code calls a method that throws SomeException, that code must also be in a try-catch or its method must also specify throws SomeException.
Because of the first two checks, the compiler can detect whether a checked exception can actually be thrown in a certain block of code. As a result, this leads to a third property:
If the catch clause of a try-catch block declares an Exception type that cannot occur in the try block, then a compile error is generated. The compiler does this primarily to tell you that you've made an error: you're dealing with an exception that will never be thrown.
SQLException is a checked exception so it is subject to those rules. None of the lines of code (or the methods they call) in the try block below can ever throw a SQLException so the compiler tells you via a compile error.
try {
suggestionWidgetModel.clear();
for (Suggestion suggestion : suggestions)
suggestionWidgetModel.addElement(suggestion.getCaption());
if (!suggestions.isEmpty())
suggestionWidget.setSelectedIndex(0);
}
catch (SQLException e) // This line is my problem, Could someone help me how to fix this? Thanks..
{
e.printStackTrace();
}

Rethrowing checked exceptions

public void foo() {
begin();
try {
...
commit();
} catch (Exception e) {
rollback();
throw e;
}
}
In the sample above, there is an error because foo has no throws Exception. Adding that wouldn't make do the method's usability a lot of good either.
What's the best way to do this? How do you do something if an error occurs without really "handling" the error?
Since Java 8 we use
/**
* Cast a CheckedException as an unchecked one.
*
* #param throwable to cast
* #param <T> the type of the Throwable
* #return this method will never return a Throwable instance, it will just throw it.
* #throws T the throwable as an unchecked throwable
*/
#SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
throw (T) throwable; // rely on vacuous cast
}
You can rethrow a checked exception, but only by avoiding the compilers checked exception validation.
public void foo() throws MyCheckedException {
begin();
try {
...
commit();
} catch (Exception e) {
rollback();
// same as throwing an exception without the compiler knowing.
Thread.currentThread().stop(e);
}
}
Before you use stop() you should read http://download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Thread.currentThread().stop(e) .. is behaviorally identical to Java's throw operation, but circumvents the compiler's attempts to guarantee that the calling method has declared all of the checked exceptions that it may throw:
At least two approaches come to mind, which are usually going to be combined depending on what you want foo to do:
1. Catch and rethrow only the relevant exceptions
There are only so many exceptions the code in your main flow can throw (probably mostly SqlExceptions). So only catch and rethrow those, and declare that you're doing so. More to the point, rethrow only the ones you're not actually handling (in your simplified sample code, you're not handling any, but your real life code is probably more subtle).
Mind you, some of the exceptions may be runtime exceptions, and so you may want to combine this with the below.
2. Don't catch the exception at all
Like this:
// Signature changes to include any exceptions that really can be thrown
public void foo() throws XYZException, ABCException {
// A flag indicating that the commit succeeded
boolean done = false;
begin();
try {
// Don't have any `return` statements in here (or if you do,
// set `done` to `true` first)
...
commit();
done = true; // Commit didn't throw an exception, we're done
} finally {
// finally clause always happens regardless
if (!done) {
// We must be processing an exception; rollback
try {
rollback();
} catch (Exception e) {
// quash it (e.g., leave this block empty), we don't want
// to mask the real exception by throwing a different one
}
}
}
}
Naturally your signature needs to include any exceptions that may be thrown in the main flow, but that's what you're trying to do, if I'm understanding you correctly.
Again, you may well combine these two approaches, because you may want to handle some exceptions and not others.
Wrap it with some RuntimeException which is unchecked.
Adding that wouldn't make do the method's usability a lot of good either.
No. It will be good at documentation, also caller will take care handling it.
Also See
exception-thrown-inside-catch-block-will-it-be-caught-again
throws-or-try-catch
I'd say that in this case rolling back is handling the exception appropriately. It's one of the few cases where it's legitimate to catch and re-throw.
Simply catching and logging an exception is not what I would consider handling. Rather than rethrowing, in that case I'd rather see checked exceptions added to the method signature and let it bubble up.
you may throw a subclass of RuntimeException - they don't require a catch()
the key point is, why should you throw a new Exception from a catch block.
if you use catch then handle your exception there in your catch. If you have to inform the caller method with an exception, then don't catch the exception with try-catch, instead, sign your method with throws and let the caller catch the e xception.
or throw a RuntimeException, i find this idea less useful because of lack of readability, then you don't need to sign your method with throws.
Here you've chanced on one of the biggest religious schisms in the Java, ( if not wider ) , world. It boils down to those that feel, as TJ seems to, and I do too, that checked exceptions are valuable for many reasons, VS the Rod Johnson/Spring school that in the design of Java, checked exceptions were used in many instances where they shouldn't, say closing a resultset or socket, so because it was wrongly used in many cases, it makes them useless so all exceptions should be unchecked. There are many classes in the Spring framework that are very thin wrappers around standard Java objects, but convert checked exceptions to unchecked. It drives me berserk!
Anyway, put me down as strongly agreeing with everything TJ has said, but know that you'll probably never find a "right" answer.
It's worth mentioning some advances in this area.
First, in Java 7, it's possible to catch and throw generic exceptions, as long as what's declared inside the try block is caught or declared in the outer block. So this would compile:
void test() throws SQLException {
try {
conn.commit();
} catch (Throwable t) {
// do something
throw t;
}
}
This is well explained here : http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
Another way is described here : http://blog.jooq.org/2012/09/14/throw-checked-exceptions-like-runtime-exceptions-in-java/
The reason you may want to use that has often to do with lambdas, or throwing exceptions from some generic methods. I ran into this when I wanted to replace repeating constructs of:
try {
do_operation
flag_success
} catch (Throwable e) {
flag_error
throw e;
}
With using a method of:
public static void wrapExec(RunnableT s) {
try {
s.run();
flag_success
} catch (Throwable t) {
flag_error
doThrow(t);
}
}
and therefore replacing the whole try/catch block with just
wrapExec(()->{do_operation})

Categories