skip to Main Content

I am getting below error randomly.
Here is my stack

  • App deployed on vercel is talking to Atlas mongodb (free tier)
  • Nodejs – 18.16.1
  • nextjs 13
  • mongodb package version – 5.8.1
ERROR   Unhandled Promise Rejection     {"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"MongoServerSelectionError: connection timed out","reason":{"errorType":"MongoServerSelectionError","errorMessage":"connection timed out","reason":{"type":"ReplicaSetNoPrimary","servers":{},"stale":false,"compatible":true,"heartbeatFrequencyMS":10000,"localThresholdMS":15,"setName":"Cluster0-shard-0","maxElectionId":null,"maxSetVersion":null,"commonWireVersion":0,"logicalSessionTimeoutMinutes":null},"stack":["MongoServerSelectionError: connection timed out","    at Timeout._onTimeout (/var/task/node_modules/mongodb/lib/sdam/topology.js:278:38)","    at listOnTimeout (node:internal/timers:569:17)","    at process.processTimers (node:internal/timers:512:7)"]},"promise":{},"stack":["Runtime.UnhandledPromiseRejection: MongoServerSelectionError: connection timed out","    at process.<anonymous> (file:///var/runtime/index.mjs:1186:17)","    at process.emit (node:events:525:35)","    at emit (node:internal/process/promises:149:20)","    at processPromiseRejections (node:internal/process/promises:283:27)","    at process.processTicksAndRejections (node:internal/process/task_queues:96:32)"]}
[ERROR] [1692852863980] LAMBDA_RUNTIME Failed to post handler success response. Http response code: 400.
RequestId: 971d9da3-a51d-4511-a561-22d5702be848 Error: Runtime exited with error: exit status 128

When this error occurs, server responds with http 500 error code.

Can someone tell me why this would happen? Is it due to free tier of Atlas Mongodb?

Below code shows how I am connecting to mongodb.
Clientpromise is being imported and then used to do db operations in other files.

import { MongoClient } from "mongodb";

//mongodb+srv://sjhfjhfjhf/ongodb.net/awesomedb?serverSelectionTimeoutMS=60000
const uri = process.env.MONGODB_URI;
const options = {
  //useUnifiedTopology: true,
  useNewUrlParser: true,
  serverSelectionTimeoutMS: 59000,
};

let client;
let clientPromise;

if (!process.env.MONGODB_URI) {
  throw new Error("Please add your Mongo URI to .env.local");
}

if (process.env.NODE_ENV === "development") {
  // In development mode, use a global variable so that the value
  // is preserved across module reloads caused by HMR (Hot Module Replacement).
  if (!global._mongoClientPromise) {
    client = new MongoClient(uri, options);
    global._mongoClientPromise = client.connect();
  }
  clientPromise = global._mongoClientPromise;
} else {
  // In production mode, it's best to not use a global variable.
  client = new MongoClient(uri, options);
  clientPromise = client.connect();
}

// Export a module-scoped MongoClient promise. By doing this in a
// separate module, the client can be shared across functions.
export default clientPromise;

Here is how I am firing the query


import { ObjectId } from 'mongodb';
import clientPromise from '../../lib/mongodb'
import { connectToDatabase, slugify } from './blog';

export async function saveAdToMongoDB(adObj) {
  try {
    const collection = (await clientPromise).db().collection("ads");  
    let catslug = slugify(adObj.businessCategory)
    let slug = slugify( adObj.businessName + "-" + adObj.city + "-" + catslug)
    adObj.slug = slug ;
    adObj.catslug = catslug;
    let advertisementObject = {...adObj, status:"pending",image:""}
    let result = await collection.insertOne(advertisementObject);
  } catch (err) {
    console.error("Failed to save ad to MongoDB:", err);
  } 
}

I upgraded mongodb and nextjs packages but it did not help. Most of other solutions on internet are talking about firewall and ip whitelisting. But I do not think that’s causing the issue.

2

Answers


  1. I’m not a node developer, but this error looks more or less the same as in other languages, so:

    The error reason is mentioned in this json (which is a driver side representation of the server state)

        {
            "errorType": "Runtime.UnhandledPromiseRejection",
            "errorMessage": "MongoServerSelectionError: connection timed out",
            "reason": {
                "errorType": "MongoServerSelectionError",
                "errorMessage": "connection timed out",
                "reason": {
                    "type": "ReplicaSetNoPrimary",
                    "servers": {},
                    "stale": false,
                    "compatible": true,
                    "heartbeatFrequencyMS": 10000,
                    "localThresholdMS": 15,
                    "setName": "Cluster0-shard-0",
                    "maxElectionId": null,
                    "maxSetVersion": null,
                    "commonWireVersion": 0,
                    "logicalSessionTimeoutMinutes": null
                },
                "stack": ["MongoServerSelectionError: connection timed out", "    at Timeout._onTimeout (/var/task/node_modules/mongodb/lib/sdam/topology.js:278:38)", "    at listOnTimeout (node:internal/timers:569:17)", "    at process.processTimers (node:internal/timers:512:7)"]
            },
            "promise": {},
            "stack": ["Runtime.UnhandledPromiseRejection: MongoServerSelectionError: connection timed out", "    at process.<anonymous> (file:///var/runtime/index.mjs:1186:17)", "    at process.emit (node:events:525:35)", "    at emit (node:internal/process/promises:149:20)", "    at processPromiseRejections (node:internal/process/promises:283:27)", "    at process.processTicksAndRejections (node:internal/process/task_queues:96:32)"]
        }
    

    The key point is here ReplicaSetNoPrimary. This error type says that at the time when error had happened, the driver didn’t see any primary which made impossible any writing. So the MongoServerSelectionError error is expected.

    What you can do:

    1. Try any "read" operation with enabled reading from secondaries via adding &readPreference=secondaryPreferred to the connection string. This option will allow you to use secondaries for reading.
    2. Enable useUnifiedTopology: true,. I’m not 100% confident what is this option about, you can read about it here. but I assume it might allow more correct/modern server selection handling.
    3. Check server logs and what happened at the error time there. You use mongodb+srv in the connection string. I assume you use Mongo Atlas. If so, then you can check atlas logs to see what server is the primary when the error happens. It might be that no primary elected at the error time. It will explain the driver error, then you will need investigate the server behavior, but I would defer further investigation steps until you will provide the results of what I mentioned above.
    Login or Signup to reply.
  2. It’s a combination of limitations of free Atlas tier and Vercel hosting.

    When you exhaust 500 connections quota, you get connection timeout. See this answer https://stackoverflow.com/a/76905054/1110423 for details.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search