domino
domino

Reputation: 2165

Handling java exceptions thrown by listeners

Take a situation where you are writing a library for objects meant to run asynchronously. To notify the caller of the status of the asynchronous object, the caller has to implement the listener interface.

Now, when using listeners, there's a chance that the listener will do something wrong which will cause an exception to be thrown in the library object.

Example

public interface SomeListener {
    public void progressNotification(int status);
}

public class SomeClass {
    SomeListener listener = null;
    …
    public void setListener(SomeListener listener) {
        this.listener = listener;
    }
    …
    public void someRandomMethod() {

        int progressStatus = 0;
        //Do some stuff here that updates progressStatus

        //then notify the caller
        if (listener != null) {
            listener.progressNotification(progressStatus);
        } 
    }
}

public class CallerClass implements SomeListener{
    public void progressNotification(int status) {
        //do something that will throw an exception 
        //e.g assume status is 0
        int x = 200/status; //this will throw an ArithmeticException because of division by zero
    }
}

If SomeClass doesn't catch the exception and deal with it, this will cause any code after listener.progressNotification(progressStatus); to not be executed leaving the object in an "incorrect" state.

So my question is, what is the best way to deal with this kind of exception within the library?

I have seen one library that does this:

    if (listener != null) {
        try {
            listener.progressNotification(progressStatus);
        }catch (Thrwowable th) {
            System.err.println("An uncaught throwable " + th);
        }
    } 

which doesn't look right to me.

Upvotes: 4

Views: 5678

Answers (3)

JB Nizet
JB Nizet

Reputation: 691745

To me, the contract of the listener should be well-defined:

  • it must return fast (i.e. not pause or sleep the thread, etc.),
  • it must not throw any runtime exception.

If it does throw a runtime exception, the listener breaks the API contract, and it's thus a bug of the client code of your API, not a bug of the API itself.

I wouldn't do anything other than defining and documenting the contract clearly, and explaining the potential impact of breaking the contract (i.e. undeterministic state, whatever). If the client really wants to protect himself against a programming error, he can still wrap all the listener code inside a try/catch as your example shows.

Upvotes: 7

Nathan Hughes
Nathan Hughes

Reputation: 96395

If you don't want a badly-behaved listener to stop all notifications for everybody, then that kind of exception-handling is what you need to do. I do have some nitpicks. I'd log it instead of writing it to stderr, of course. And catching Throwable is not great, there are some things (out of memory errors, for one thing) you might as well let go uncaught. But the basic idea is ok.

Upvotes: 1

Kowser
Kowser

Reputation: 8261

It is same for all, there is nothing we can do for RuntimeException. And this is why they are marked unchecked exception. Here is a nice read regarding unchecked exception.

It clearly specifies this:

Runtime exceptions can occur anywhere in a program, and in a typical one they can be very numerous. Having to add runtime exceptions in every method declaration would reduce a program's clarity. Thus, the compiler does not require that you catch or specify runtime exceptions (although you can).

So, no need to worry about it.

But obviously if it there is any scenario there might be any Checked exception, they needs to be handled properly.

Additionally it is a good practice to document possible exception which might be raised by a method.

Upvotes: 2

Related Questions