顶点和未捕获的异常

  • 本文关键字:异常 顶点 vert.x
  • 更新时间 :
  • 英文 :


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

接下来会发生什么?如果从系统中删除垂直状态,是否有类似于erlang主管的机制来重新启动垂直状态?

关于这方面的文件不是很清楚。

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

问候

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

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

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

Update2:使用Vertx.exceptionHandler注册处理程序

Vert.x是关于相同风格的异步编程,主要由回调处理程序突出显示。

要处理部署失败的情况,您必须首先采用编程方式,即您必须通过部署vertical以编程方式部署您的vertical,提供一个将用部署结果填充的完成处理程序,下面是一个使用Java的示例(由于您没有选择特定的语言,我将尽我所能),其中:

  • MainVerticle:是您的垂直部署(主要用于部署其他垂直部署)
  • some.package.MyVerticle:是您真正的vertical,请注意,我在这里使用了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...
      }
    });
  }
}

现在,当谈到"消息传递失败"时,更难强调特定的情况,因为它可能发生在许多地方,并代表消息传递的两端。

如果你想在发送消息时注册一个失败案例处理程序,你可以实例化一个代表它可以写入的流的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());
});

要在前面的答案中添加一位,如果您想对所有未捕获的异常做出反应,请在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(), ""));
    }
});

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

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

最新更新