MARTIMM / raku-mongodb-driver

MongoDB driver for Raku
Artistic License 2.0
18 stars 8 forks source link

No exceptions are raised when there is a socket error #35

Open Zer0-Tolerance opened 1 month ago

Zer0-Tolerance commented 1 month ago

Hi, While doing doing some more testing I've discovered something wrong about exception handling, look at this snippet that is trying to connect to a MongoDB server that is not actually running:

use BSON::Document;
use MongoDB::Client;
use MongoDB::Database;
use MongoDB::Collection;
# Native MongoDB driver
my MongoDB::Client $client;
my MongoDB::Database $db;
my MongoDB::Collection $col;

try {
  $client .= new(:uri("mongodb://127.0.0.1:27017"));
  $db = $client.database('Test');
  $col = $db.collection('test');
  CATCH {
    default {
      say "Mongo exception: ",.^name, '→ ', .Str;
    }
  }
}

No exception are raised , you get only log in MongoDB.log telling you that the server is down.

2024-07-12 07:20 UTC

39.881059 [E][7][Wire][121]: 127.0.0.1:27017: Failed to resolve host name '127.0.0.1' with family 2.
Error: nodename nor servname provided, or not known
39.881729 [W][7][Monitor][422]: no response from server 127.0.0.1:27017
39.883154 [I][7][Server][168]: Server status of 127.0.0.1:27017 is ST-Unknown
39.889115 [I][7][Client][595]: Client '6F44E7DDB4DE902F8A6523F9DDB480ECA1137272' topology is TT-Single

So how can one detect a socket error in that case as there is no exception to catch ?

MARTIMM commented 1 month ago

I don't know if that was according to the protocol of MongoDB, I'll have to look that up.

Zer0-Tolerance commented 1 month ago

isn't it possible to catch Failed to resolve host name '127.0.0.1' with family 2. Error: nodename nor servname provided, or not known and similar network errors ? I've tried to modified wire.rakumod to trigger a fatal-message but my main program is not getting the exception so maybe it's just an issue related to propagating the exception to the calling code ? One of the main use case would be detecting disconnection from socket pool and then trigger reconnection of the pool. As of now it seems to get stuck when you get "Not connected !" exception which seems to happen not very often but after a huge amount of request in a replicaset.

MARTIMM commented 1 month ago

I haven't yet found the developer docs about a driver's behavior in case of unavailable servers.

There is, however, another way to find out if servers aren't running. There is the timeoutMS option. This one replaces several other options. The option has not yet been implemented in this driver, so I must implement it. I can imagine the behavior after the implemention being something like an empty doc returned with the ok field set to 0.