Verticles 和未捕获的异常

Verticles and uncaught exceptions

考虑其中一个 Verticle 抛出未捕获异常的场景。

接下来会发生什么? 如果从系统中删除了 Verticle 状态,是否有一些类似于 erlang supervisors 的机制来重启 Verticle?

这方面的文档不是很清楚。

根据评论更新: 我最感兴趣的是从接收到的消息的处理程序中抛出异常的情况(通过总线)

此致

Vert.x都是大同小异的风格,异步编程,主要是callback handlers突出

要处理部署失败的情况,您必须首先采用编程方式,即您必须以编程方式部署您的 Verticle,比方说,部署 Verticle 提供一个完成处理程序将填充部署结果,这里是使用 Java 的示例(因为您没有选择特定语言,我会尽力而为)其中:

  • MainVerticle:是你的部署verticle(主要用于部署其他verticle)
  • some.package.MyVerticle: 是你真正的verticle,注意我这里用的是id不是实例
public class MainVerticle extends AbstractVerticle {  
  public void start() {
    vertx.deployVerticle("some.package.MyVerticle", res -> {
      if (res.succeeded()) {
        // Do whatever if deployment succeeded
      } else {
        // Handle deployment failure here...
      }
    });
  }
}

现在谈到 'messaging failures' 时,将很难突出显示特定案例,因为它可能出现在许多地方并代表消息传递的两端。

如果您想在发送消息时注册一个失败案例处理程序,您可以实例化一个 MessageProducer<T> 表示它可以写入的流,然后在其上注册一个异常处理程序:

EventBus eb = vertx.eventBus();
MessageProducer<String> sender = eb.sender("someAddress");
sender.exceptionHandler(e -> { 
  System.out.println("An error occured" + e.getCause()); 
});
sender.write("Hello...");

另一方面,您可以以几乎相同的方式处理读取接收到的消息时的失败情况,但这次使用 MessageConsumer<T>

EventBus eb = vertx.eventBus();
MessageConsumer<String> receiver = eb.consumer("someAddress");
receiver.exceptionHandler(e -> { 
  System.out.println("An error occured while readeing data" + e.getCause()); 
}).handler(msg -> {
  System.out.println("A message has been received: " + msg.body());
});

我已经回答了我自己的部分问题(借助测试程序)

当事件处理程序中抛出异常时,异常会被 vert.x 捕获并吞没(忽略)。事件处理程序将处理下一条消息。

更新:该应用程序可以注册一个异常处理程序并将所有未捕获的 Throwable 传递给该处理程序。在那里你可以执行额外的一般处理

更新2:使用Vertx.exceptionHandler注册处理程序

要对之前的答案做一点补充,如果你想对所有未捕获的异常做出反应,请在 vertx 对象上注册处理程序,如下所示:

vertx.exceptionHandler(new Handler<Throwable>() {       
    @Override
    public void handle(Throwable event) {
        // do what you meant to do on uncaught exception, e.g.:
        System.err.println("Error");
        someLogger.error(event + " throws exception: " + event.getStackTrace());
    }
});

我运行进入类似的东西。当在 Verticle 中处理消息的过程中发生异常时,我只想用异常进行回复。

我们的想法是将异常一直冒泡到应用程序的入口点,在入口点可以决定如何处理失败,同时捕获整个堆栈。

为了完成它我写了这个函数:

protected ReplyException buildReplyException(Throwable cause, String message)
    {
        ReplyException ex = new ReplyException(ReplyFailure.RECIPIENT_FAILURE, -1, message);
        ex.initCause(cause);
        return ex;
    }

然后我用它来构建处理程序或回复处理程序,如下所示:

reply -> {
    if (reply.succeeded()) {
        message.reply(true);
    } else {
        message.reply(buildReplyException(reply.cause(), ""));
    }
});

这样发送原始消息的人将得到一个失败的响应,其中包含一个异常原因,其中填充了完整的堆栈跟踪。

这种方法对我在处理消息时处理错误非常有效。