[英]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.