You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
At the moment the getMongodbClient function doesn't implement any error handling, apart from printing a warning when it cannot instantiate MongoClient. This catch captures only a few failure modes, for instance when the uri scheme is incorrect, like "incorrect-mongodb-uri".
The correct implementation leaves out many failures modes which manifest as runtime issues when using Indiekit. See the snippet below for details.
Describe the solution you’d like
A UI element like a toast, a dialog, or something else could notify the user about database connection issues as soon as Indiekit starts.
I can think of the following scenarios which Indiekit should handle:
Incorrect uri scheme. Fails at step 1. This is handled by the current implementation, and a warning is printed to console.
Correct uri scheme but it includes a port, which in some cases cannot actually be included (mongodb+srv cannot include a port).
Correct uri scheme but incorrect MongoDB credentials.
Correct uri scheme and correct MongoDB credentials, but nonexistent database.
import{MongoClient,ServerApiVersion}from"mongodb";import{uri}from"./config.js";constusername="john";constpassword="wrong-password";consthost="cluster123.abc.mongodb.net";constport=27017;// 1. incorrect uri scheme. Fails at step 1// const uri = "incorrect-mongodb-uri";// 2. correct uri scheme but it fails because mongodb+srv cannot include a port. Fails at step 1// const uri = `mongodb+srv://${username}:${password}@${host}:${port}`;// 3. correct uri scheme but nonexistent database. Fails at step 2// const uri = `mongodb+srv://${username}:${password}@${host}`;// 4. correct uri (which I have in config.js)// 5. correct uri and credentials, but nonexistent database// const db_name = "nonexistent-database";constdb_name="indiekit";construn=async()=>{// step 1: instantiate MongoClientletclient;try{client=newMongoClient(uri,{serverApi: {deprecationErrors: true,strict: true,version: ServerApiVersion.v1,},// serverSelectionTimeoutMS: 1, // this will let us instantiate MongoClient, but it will fail at step 2serverSelectionTimeoutMS: 10000,});}catch(ex){// Example: Invalid scheme, expected connection string to start with "mongodb://" or "mongodb+srv://"// Example: mongodb+srv URI cannot have port number// There is no db connection to close because there is no client in the first placereturn{error: newError(ex.message||"could not create MondoDB client"),};}// step 2: connect to MongoDBleterror;try{awaitclient.connect();}catch(ex){// Example: querySrv ENOTFOUND _mongodb._tcp.cluster123.abc.mongodb.net// Example: MongoServerSelectionError: Server selection timed out after 1 mserror=newError(ex.message||"could not connect to MongoDB");}if(error){awaitclient.close();return{ error };}letdb_names=[];try{db_names=(awaitclient.db(db_name).admin().listDatabases()).databases.map((db)=>db.name);if(!db_names.includes(db_name)){error=newError(`database ${db_name} does not exist`);}}catch(ex){error=newError(ex.message||`could connect to MongDB but could not connect to database ${db_name}`);}if(error){awaitclient.close();return{ error };}// Database exists, so we return the MongoDB client. The caller will have to// call `await client.close()` when appropriate.return{value: client};};run().then((result)=>{const{ error,value: client}=result;if(error){console.trace(error);}if(client){client.close().then(()=>{console.info(`connection closed`);});}});
Describe alternatives you’ve considered
No response
Additional context
I'm writing here how I found out about the need for better error handling in regards to the MongoDB connection.
I was using MongoDB Atlas as my database, and I was connecting to it from my laptop and from a Google Cloud Compute Engine VM.
The connection from my laptop was fine, and I could use Indiekit without any issue. However, when launching Indiekit from the VM, I had these issues:
Indiekit would take ~30 seconds to start
I could not create notes, nor query them
I could not upload media, nor query them
Long story short, the reason for those ~30 seconds was that MongoClient could not establish a connection to Atlas, and would throw after 30000ms (the default value for serverSelectionTimeoutMS). Indiekit printed a warning but kept running. This means that client was now undefined, and I encountered runtime exceptions when executing posts.insertOne() or media.findOne(), because posts and media were undefined.
And why wasn't I able to connect to Atlas from my VM?
Simple. I had forgotten about whitelisting the IP of my VM in Atlas. 🤦♂️
The text was updated successfully, but these errors were encountered:
Is your feature request related to a problem?
At the moment the
getMongodbClient
function doesn't implement any error handling, apart from printing a warning when it cannot instantiateMongoClient
. This catch captures only a few failure modes, for instance when the uri scheme is incorrect, like"incorrect-mongodb-uri"
.The correct implementation leaves out many failures modes which manifest as runtime issues when using Indiekit. See the snippet below for details.
Describe the solution you’d like
A UI element like a toast, a dialog, or something else could notify the user about database connection issues as soon as Indiekit starts.
I can think of the following scenarios which Indiekit should handle:
mongodb+srv
cannot include a port).Describe alternatives you’ve considered
No response
Additional context
I'm writing here how I found out about the need for better error handling in regards to the MongoDB connection.
I was using MongoDB Atlas as my database, and I was connecting to it from my laptop and from a Google Cloud Compute Engine VM.
The connection from my laptop was fine, and I could use Indiekit without any issue. However, when launching Indiekit from the VM, I had these issues:
Long story short, the reason for those ~30 seconds was that
MongoClient
could not establish a connection to Atlas, and would throw after 30000ms (the default value forserverSelectionTimeoutMS
). Indiekit printed a warning but kept running. This means thatclient
was nowundefined
, and I encountered runtime exceptions when executingposts.insertOne()
ormedia.findOne()
, becauseposts
andmedia
wereundefined
.And why wasn't I able to connect to Atlas from my VM?
Simple. I had forgotten about whitelisting the IP of my VM in Atlas. 🤦♂️
The text was updated successfully, but these errors were encountered: