Search code examples
javaguavaevent-bus

Bring Up Exceptions in Google Guava EventBus


Google Guava EventBus swallows exceptions and just log them.

I wrote a very simple application to explain my approach:

public class SimplePrinterEvent {
 @Subscribe
 public void doPrint(String s) {
    int a = 2/0; //This is to fire an exception
    System.out.println("printing : " + s );
  }
}

Demo

public class SimplePrinterEventDemo {
  public static void main(String[] args) {

    EventBus eventBus = new EventBus();
    eventBus.register(new SimplePrinterEvent());
    try{
        eventBus.post("This is going to print");
    }
    catch(Exception e){
        System.out.println("Error Occured!");
    }
  }
}

This will never come to the catch block!

So I added a SubscriberExceptionHandler and overrided handleException().

EventBus eventBus = new EventBus(new SubscriberExceptionHandler() {

        @Override
        public void handleException(Throwable exception,
                SubscriberExceptionContext context) {
            System.out.println("Handling Error..yes I can do something here..");
            throw new RuntimeException(exception);
        }
    });

It allows me to handle the exception inside the handler , but my requirement is to bring that exception to the top layer, where I handle them.

EDIT: An Old Solution I found in some websites . (This is working with guava v18)

public class CustomEventBus extends EventBus {
@Override
void dispatch(Object event, EventSubscriber wrapper) {
    try {
        wrapper.handleEvent(event);
    } catch (InvocationTargetException cause) {
        Throwables.propagate(Throwables.getRootCause(cause));
    }
 }
}

Solution

  • Following trick works to me:

    Latest EventBus class has a method called handleSubscriberException() which you need to override in your extended EventBus class: (Here I have included both solutions, only one will work for your version)

    public class CustomEventBus extends EventBus {
      //If version 18 or bellow
      @Override
      void dispatch(Object event, EventSubscriber wrapper) {
        try {
            wrapper.handleEvent(event);
        } catch (InvocationTargetException cause) {
            Throwables.propagate(Throwables.getRootCause(cause));
        }
      }
      //If version 19
      @Override
      public void handleSubscriberException(Throwable e, SubscriberExceptionContext context) {
        Throwables.propagate(Throwables.getRootCause(e));
      }
    }