簡體   English   中英

Google Guava EventBus和事件處理程序中的異常

[英]Google Guava EventBus and Exceptions in Event Handlers

Guava EventBus文檔說“一般情況下,處理程序不應拋出。如果這樣做,EventBus將捕獲並記錄異常。這很少是錯誤處理的正確解決方案,不應該依賴;它僅用於幫助在開發過程中發現問題。“

如果您知道可能發生某些異常,則可以使用EventBus注冊SubscriberExceptionHandler並使用它來處理這些異常。

但是如果發生未處理的異常會發生什么? 通常情況下,我希望一個未處理的異常“冒泡”調用鏈。 使用SubscriberExceptionHandler時,我可以訪問事件處理程序中拋出的原始異常,我只想重新拋出它。 但我無法弄清楚如何。

那么,無論是否使用SubscriberExceptionHandler,如何確保事件處理程序中的意外異常不會被“吞噬”?

任何幫助將不勝感激。

番石榴不會讓異常泡沫起來。 它被迫在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);
    }
}

如果要處理未經檢查的異常,可以實現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冒泡。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM