Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Google Guava事件总线和事件处理程序中的异常_Java_Guava_Event Bus - Fatal编程技术网

Java Google Guava事件总线和事件处理程序中的异常

Java Google Guava事件总线和事件处理程序中的异常,java,guava,event-bus,Java,Guava,Event Bus,Guava EventBus文档中说 处理程序通常不应抛出。如果抛出,EventBus将捕获并记录异常。这很少是错误处理的正确解决方案,不应依赖它;它仅用于帮助在开发过程中发现问题 如果您知道可能会发生某些异常,可以向EventBus注册SubscriberExceptionHandler并使用它来处理这些异常 但是,如果发生未处理的异常,会发生什么情况?通常,我希望有一个未处理的异常来“冒泡”调用链。使用SubscriberExceptionHandler时,我可以访问事件处理程序中引发的原始

Guava EventBus文档中说 处理程序通常不应抛出。如果抛出,EventBus将捕获并记录异常。这很少是错误处理的正确解决方案,不应依赖它;它仅用于帮助在开发过程中发现问题

如果您知道可能会发生某些异常,可以向EventBus注册SubscriberExceptionHandler并使用它来处理这些异常

但是,如果发生未处理的异常,会发生什么情况?通常,我希望有一个未处理的异常来“冒泡”调用链。使用SubscriberExceptionHandler时,我可以访问事件处理程序中引发的原始异常,我只想重新引发它。但我不知道怎么做

那么,无论是否使用SubscriberExceptionHandler,如何确保事件处理程序中的意外异常不会被“吞没”


非常感谢您的帮助。

如果您想处理未检查的异常,您可以实现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
将使用您的异常处理程序,它将允许运行时异常冒泡。

Guava不会允许异常冒泡。它被迫在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);
    }
}

感谢并为迟来的答复感到抱歉,我已经在一个不同的项目上工作了一段时间。这正是我需要的。我想在调用事件之前不可能包含callstack?到目前为止,异常的调用堆栈从调用该事件的EventBus开始。