Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 804
domino Avatar asked Dec 28 '22 15:12

domino


1 Answers

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.

like image 125
JB Nizet Avatar answered Jan 11 '23 09:01

JB Nizet