如何使用Vert.x捕获异步代码中的错误

时间:2019-02-02 22:32:41

标签: vert.x vertx-verticle

使用Node.js,我们可能会使用域来捕获异步代码中引发的错误,如下所示: https://medium.com/@the1mills/using-node-js-domains-in-production-797105a4c302

以这种方式使用域可以使我们将错误固定在特定的请求上,这样我们就可以发送响应并进行清理,并允许我们的服务不断发展。

使用Golang,有这样的错误处理中间件,我们可以用来捕获错误并将其固定到特定请求。

func Error() Adapter {
    return func(next http.HandlerFunc) http.HandlerFunc {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            defer func() {
                if err := recover(); err != nil {

                    log.Error("Caught error in defer/recover middleware: ", err)

                    // ...

                    json.NewEncoder(w).Encode(struct {
                        Message string
                    }{
                        message,
                    })

                }
            }()

            log.Info("We are handling errors with defer.")
            //next.ServeHTTP(w, r)
            next(w,r);
        })
    }
}

您可能已经知道,错误中间件只是在调用任何其他api路由之前注册的,如果发生紧急情况,延迟将捕获它。我不知道,如果它与“分够程”,但它适用于运行目前的够程。

所以我的问题是-使用Vertx时-如果一个请求引起错误,我们如何防止进程崩溃?理想情况下,我们可以记录错误,并为该请求发送响应并继续进行修改。

2 个答案:

答案 0 :(得分:1)

使用Vert.x,您不需要:

Vertx vertx = Vertx.vertx();

Router router = Router.router(vertx);

router.get("/").handler((req) -> {
    System.out.println("Got something");
    // We crash
    throw new RuntimeException();
});

vertx.createHttpServer().requestHandler(router).listen(8080);

运行此示例,您将看到Vert.x捕获异常。

但是,假设您要自己处理一些错误。然后使用errorHandler()

router.errorHandler(500, (ctx) -> {
    ctx.response().end("Got something bad");
});

答案 1 :(得分:0)

@Alexey的答案不是我想要的,这是问题所在:

router.route("/foo1").handler(h -> {
  throw new RuntimeException("error1");
});


router.route("/foo2").handler(h -> {
   vertx.runOnContext(v -> {
      throw new RuntimeException("error2");
   });
});


router.route().failureHandler(ctx -> {
  ctx.response().end("We failed here!");
});

如果您打了foo1路由,则该错误将被failHandler捕获,并将响应发送到浏览器。但是如果您点击foo2路由,我们将得到一个未处理的运行时异常:

SEVERE: Unhandled exception
java.lang.RuntimeException: shit2
        at huru.MainVerticle.lambda$start$2(MainVerticle.java:96)
        at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
        at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:462)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:844)

所以我正在寻找有关如何处理vertx异步代码中引发的错误的答案。