How to catch exception when creating MongoClient instance

非 Y 不嫁゛ 提交于 2019-11-29 15:46:08

The server connections are created on daemon threads. So long story short you'll not to able to check the connection related errors while creating the Mongo Client.

You'll have to delay your connection check when you make your first real database which involves a read or write.

Just for demonstration purposes for you to get an idea.

MongoClient mongoClient = new MongoClient("127.0.34.1", 89);
DB db = mongoClient.getDB("test");
try {
   db.addUser("user", new char[] {'p', 'a', 's', 's'});
} catch(Exception e) { MongoTimeoutException exception}

MongoSocketOpenException from Deamon Thread

INFO: Exception in monitor thread while connecting to server 127.0.34.1:89
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.connection.SocketStream.open(SocketStream.java:63)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:116)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.ConnectException: Connection refused: connect

MongoTimeoutException from Main Thread

Exception in thread "main" com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=127.0.34.1:89, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, 
caused by {java.net.ConnectException: Connection refused: connect}}]
at com.mongodb.connection.BaseCluster.createTimeoutException(BaseCluster.java:375)

So wrap code in try catch block with MongoTimeoutException and it will work okay for checking connection related errors.

It's pretty simple and elegant:

  1. Redirect System.err to a file:

    ByteArrayOutputStream file=new ByteArrayOutputStream();
    System.setErr(new PrintStream(file));
    
  2. Connect to the server with your MongoClient and your MongoCredentials:

    MongoCredential credenciales=MongoCredential.createCredential("root", "admin", "root".toCharArray());
    MongoClient client = new MongoClient(new ServerAddress("localhost"), Arrays.asList(credenciales));
    
  3. Read the error output, which is in the ByteArrayOutputStream object:

    String texto=new String(file.toByteArray());
    
  4. Check whether the Autentication failed string is present:

    if (texto.contains("'Authentication failed.'"))
       // do something;
    else
      ...
    

For anyone who stumbles upon this now. I had the same issue and tried using Macario's answer, but didn't come out with much luck. Then realized that the thread monitoring the connection is not sending it to System.err, but instead was sending it to System.out so instead of using System.err, use System.out like so:

PrintStream out = System.out;  // Save the original out stream to reset later

// Set out to a buffer
ByteArrayOutputStream file=new ByteArrayOutputStream();
System.setOut(new PrintStream(file));

mongoClient = new MongoClient(new MongoClientURI("<connection_string>")));

// Found this to be important as we need to wait for the thread to dump to out
// 1000 millis was too fast for me but 2000 did the trick
Thread.sleep(2000);

// Convert buffer to a string
String texto=new String(file.toByteArray());

System.setOut(out); // Reset out

// Check if saved out contins the error (I was looking for MongoSocketException)
if(texto.contains("MongoSocketException")){
    // Do Stuff
}
  new MongoClient("localhost", 1111);

        } catch (MongoSocketOpenException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

You just have to name the appropriate exception in the catch block. This applies to any exception. You can add as many catch blocks for each unique exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!