Matthew Alltop
Matthew Alltop

Reputation: 545

Java setOnAction subscribe to event that throws exception

Let me preface this by saying, I am not a Java programmer and have thus far been unable to understand WHY this is the case.

I'm currently working on a homework assignment that requires me to create a basic GUI using JavaFX. The functionality of this GUI requires that there are buttons that will perform CRUD operations when clicked. Currently I have everything set up properly in my Insert method:

        public void Insert() throws SQLException{

        //Insert new record here
    }

However, whenever I try to subscribe to this method using 'setOnAction', the compiler is telling me there's an unhandled exception on the event:

btnInsert.setOnAction(e ->Insert());

I'm more curious if there's a way to handle this in a relatively succinct way? I've thus far been unable to come up with a solution.

Upvotes: 1

Views: 1505

Answers (1)

Itai
Itai

Reputation: 6911

That's because Java requires you to declare all checked exceptions you throw - so whenever you call a method that may throw a checked exception, you must either catch it or declare you may throw it yourself.

See this question for an explanation of checked vs. unchecked exception (The short version - any Exception which inherits either Error or RuntimeException is unchecked, while all other exceptions are checked.)

When you are providing setOnAction with a lambda, you are actually creating an anonymous class implementation of EventHandler<ActionEvent>. Since it does not declare it throws any exceptions, neither does your anonymous class (and in fact - it can't).

So you have two options of solving the problem:

  1. Catch and handle the exception:

    btnInsert.setOnAction(e -> {
        try {
            Insert();
        } catch (SQLException ex) {
            // Log error, show error message, etc... Whichever is applicable for your application
        }
    });
    
  2. Rethrow an un-checked exception:

    btnInsert.setOnAction(e -> {
        try {
            Insert();
        } catch (SQLException ex) {
            throw new RuntimeException(ex); // Or any other subclass of RuntimeException or Error
        }
    });
    

As to choosing between the two options - Oracle's documentation says this:

Here's the bottom line guideline: 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.

Of course, this could all be moved away from the actual EventHandler, so it can be called on a method that is checked-exception-free.

Upvotes: 4

Related Questions