Verticle和未捕获的异常

时间:2015-06-22 15:27:04

标签: vert.x

考虑其中一个顶点抛出未捕获的异常的情况。

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

文档对此方面不是很清楚。

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

此致

4 个答案:

答案 0 :(得分:6)

Vert.x 是完全相同的样式,异步编程,主要由回调处理程序突出显示。

要处理部署失败案例,首先要采用编程方式,即必须以编程方式部署Verticle,让我们说部署Verticle 提供完成处理程序,填充部署结果,在这里使用 Java 进行示例(因为您没有选择特定语言,我将尽我所能),其中:

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

答案 1 :(得分:5)

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

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

更新:应用程序可以注册一个异常处理程序,并将所有未被捕获的Throwable传递给此处理程序。在那里,您可以执行其他常规处理

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

答案 2 :(得分:2)

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

答案 3 :(得分:0)

我遇到了类似的事情。当在Verticle中处理消息时发生异常时,我只想答复Exception。

想法是将异常一直冒泡回到应用程序中的入口点,在该点上可以决定如何处理故障,同时捕获整个堆栈。

为此,我编写了此函数:

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(), ""));
    }
});

这样,发送原始消息的家伙将收到失败的响应,其中包含一个原因,该原因是一个异常,上面已填充了完整的堆栈跟踪。

这种方法非常适合我在处理消息时处理错误。