2015-11-08 3 views
3

Документация Guava EventBus гласит, что «обработчики вообще не должны бросать. Если это так, EventBus будет ловить и регистрировать исключение. Это редко бывает правильным решением для ошибки и на него нельзя положиться, он предназначен только для того, чтобы помочь найти проблемы во время разработки ».Google Guava EventBus и исключения в обработчиках событий

Если вы знаете, что могут возникнуть определенные исключения, вы можете зарегистрировать SubscriberExceptionHandler с EventBus и использовать его для обработки этих исключений.

Но что происходит, если возникает необработанное исключение? Обычно я хотел бы получить необработанное исключение, чтобы «раздуть» вызывающую цепочку. При использовании SubscriberExceptionHandler у меня есть доступ к исходному исключению, которое было выбрано в обработчике событий, и я просто хочу его перестроить. Но я не мог понять, как это сделать.

Итак, как вы можете убедиться, что неожиданные исключения в обработчиках событий не «проглатываются», независимо от того, используется ли SubscriberExceptionHandler или нет?

Любая помощь была бы принята с благодарностью.

ответ

4

Если вы хотите иметь дело с непроверенными исключениями, вы могли бы реализовать метод SubscriberExceptionHandler как это:

public void handleException(Throwable exception, SubscriberExceptionContext context) { 
    // Check if the exception is of some type you wish to be rethrown, and rethrow it. 
    // Here I'll assume you'd like to rethrow RuntimeExceptions instead of 'consuming' them. 
    if (exception instanceof RuntimeException) { 
     throw (RuntimeException) exception; 
    } 

    // If the exception is OK to be handled here, do some stuff with it, e.g. log it. 
    ... 
} 

После создания класса, реализующего интерфейс SubscriberExceptionHandler, вы можете передать его экземпляр в конструктор EventBus в:

EventBus eventBus = new EventBus(new MySubscriberExceptionHandler()); 

И сделано, eventBus будет использовать ваш обработчик исключений, который позволит RuntimeExceptions пузырится вверх.

+0

Спасибо и извините за поздний ответ, мне пришлось некоторое время работать над другим проектом. Это то, что мне нужно. Я полагаю, что невозможно включить вызов, прежде чем было вызвано событие? Пока что столбец исключения начинается с EventBus, вызывающего событие. –

7

Гуава не позволит исключить пузырь. Он вынужден останавливаться внутри exceptionHandler. См. Исходный код ниже.

 /** 
     * Handles the given exception thrown by a subscriber with the given context. 
     */ 
     void handleSubscriberException(Throwable e, SubscriberExceptionContext context) { 
     checkNotNull(e); 
     checkNotNull(context); 
     try { 
      exceptionHandler.handleException(e, context); 
     } catch (Throwable e2) { 
      // if the handler threw an exception... well, just log it 
      logger.log(
       Level.SEVERE, 
       String.format(Locale.ROOT, "Exception %s thrown while handling exception: %s", e2, e), 
       e2); 
     } 
     } 

Я публикую вопрос о github. Вы можете наследовать EventBus и написать свою собственную логику обработки исключений.

package com.google.common.eventbus; 

import com.google.common.eventbus.EventBus; 
import com.google.common.eventbus.SubscriberExceptionContext; 

/** 
* A eventbus wihch will throw exceptions during event handle process. 
* We think this behaviour is better. 
* @author ytm 
* 
*/ 
public class BetterEventBus extends EventBus { 

    public BetterEventBus() {} 

    /** 
    * Creates a new EventBus with the given {@code identifier}. 
    * 
    * @param identifier a brief name for this bus, for logging purposes. Should be a valid Java 
    *  identifier. 
    */ 
    public BetterEventBus(String identifier) { 
     super(identifier); 
    } 

    /** 
    * Just throw a EventHandleException if there's any exception. 
    * @param e 
    * @param context 
    * @throws EventHandleException 
    */ 
    @Override 
    protected void handleSubscriberException(Throwable e, SubscriberExceptionContext context) throws EventHandleException { 
     throw new EventHandleException(e); 
    } 
}