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.
To me, the contract of the listener should be well-defined:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With