如何正确处理 MongoClient for VertX 中的异常

How to properly handle exceptions in MongoClient for VertX

在我的应用程序的启动方法中,我想检查提供给应用程序的 MongoDB 的凭据是否正确。如果一切正常,我将继续启动,否则,应用程序应该退出,因为它无法连接到数据库。代码片段如下:

  // Create the client
  MongoClient mongodb = null;
  try {
      mongodb = MongoClient.createShared(vertx, mongo_cnf, mongo_cnf.getString("pool_name"));
  }
  catch(Exception e) {
      log.error("Unable to create MongoDB client. Cause: '{}'. Bailing out", e.getMessage());
      System.exit(-1);
  }

如果我提供了错误的凭据,则不会调用 catch 块。然而我在控制台上得到以下信息:

  19:35:43.017 WARN  org.mongodb.driver.connection - Exception thrown during connection pool background maintenance task
com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=null, userName='user', source='admin', password=<hidden>, mechanismProperties={}}
    at com.mongodb.connection.SaslAuthenticator.wrapException(SaslAuthenticator.java:162)
    at com.mongodb.connection.SaslAuthenticator.access0(SaslAuthenticator.java:39)
... many lines

问题是:如何在我的代码中拦截这个异常并能够正确处理它?

异常发生在 mongodb 的 java 驱动程序守护线程中,因此您无法捕获它。

Vertx MongoClient 将您从与 MongoDB Java 驱动程序的直接交互中抽象出来,因此您无法修改与客户端相关的任何内容。

您可以通过反射访问 mongo 客户端实例,但由于它已经创建,您无法向其传递额外的配置。

如果您使用 com.mongodb.async.client.MongoClient,您可以传递 ServerListener,它可以访问异常并检查它(请参阅此答案以获取更多详细信息 - )。

但是只能在构建 mongo 客户端时指定 ServerListener,这发生在 Vertx MongoClient 包装器内部,无法传递此附加配置。

目前没有抛出异常,我认为这是设计错误,因为您收到了一个无法使用的对象。随意打开一个错误:https://github.com/vert-x3/vertx-mongo-client/issues

检测客户端“死亡或到达”的方法是等待连接超时:

    // Default is 30s, which is quite long
    JsonObject config = new JsonObject().put("serverSelectionTimeoutMS", 5_000);
    MongoClient client = MongoClient.createShared(vertx, config, "pool_name");
    client.findOne("some_collection", json1, json2, (h) -> {
        if (h.succeeded()) {
            //...
        }
        else {
            // Notify that the client is dead
        }
    });