考虑其中一个顶点抛出未捕获的异常的情况。
接下来会发生什么? 如果从系统中删除垂直状态是否有一些类似于erlang监督的机制来重启Verticle?
文档对此方面不是很清楚。
根据评论进行更新 我最感兴趣的是从收到的消息的处理处理程序(通过总线)抛出异常的情况
此致
答案 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(), ""));
}
});
这样,发送原始消息的家伙将收到失败的响应,其中包含一个原因,该原因是一个异常,上面已填充了完整的堆栈跟踪。
这种方法非常适合我在处理消息时处理错误。