Guava EventBus文档说明了这一点 一般来说,“处理程序不应抛出。如果这样做,EventBus将捕获并记录异常。这很少是错误处理的正确解决方案,不应该依赖它;它仅用于帮助发现问题在开发期间。“
如果您知道可能发生某些异常,可以使用EventBus注册SubscriberExceptionHandler并使用它来处理这些异常。
但是如果发生未处理的异常会发生什么?通常情况下,我希望一个未处理的异常“冒泡”调用链。使用SubscriberExceptionHandler时,我可以访问事件处理程序中抛出的原始异常,我只想重新抛出它。但我无法弄清楚如何。
那么,无论是否使用SubscriberExceptionHandler,如何确保事件处理程序中的意外异常不被“吞噬”?
非常感谢任何帮助。
答案 0 :(得分: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);
}
}
答案 1 :(得分:5)
如果你想处理未经检查的异常,你可以像这样实现SubscriberExceptionHandler的方法:
localhost
创建实现SubscriberExceptionHandler接口的类之后,可以将其实例传递给EventBus的构造函数:
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.
...
}
完成后,EventBus eventBus = new EventBus(new MySubscriberExceptionHandler());
将使用您的异常处理程序,让eventBus
冒出来。