You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中MongoDB Atlas API的Client未定义及连接异常问题

问题:Next.js SSR中MongoDB连接报错(MongoExpiredSessionError、MongoTopologyClosedError等)

在Next.js服务端渲染(SSR)组件中,我编写了以下代码用于从MongoDB Atlas的views数据库views集合获取文档浏览量,但运行时抛出大量连接相关错误。

原代码

export async function getViews(id: string) {
  try {
    await client.connect();
    const collection = client.db("views").collection("views");
    const data = await collection.findOne({id});
    if(!data) {
      return 0;
    }
    return data.views;
  }
  finally {
    await client.close();
  }
}

报错信息

MongoExpiredSessionError: Cannot use a session that has ended

MongoTopologyClosedError: Topology is closed

TypeError: Cannot read properties of undefined (reading 'close')
    at MongoClient.close (D:\XXXXX\node_modules\mongodb\lib\mongo_client.js:260:18)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async addView (webpack-internal:///(rsc)/./src/app/posts.ts:56:9)
 ⨯ unhandledRejection: TypeError: Cannot read properties of undefined (reading 'close')
    at MongoClient.close (D:\XXXXX\node_modules\mongodb\lib\mongo_client.js:260:18)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async addView (webpack-internal:///(rsc)/./src/app/posts.ts:56:9)
 ⨯ unhandledRejection: TypeError: Cannot read properties of undefined (reading 'close')
    at MongoClient.close (D:\XXXXX\node_modules\mongodb\lib\mongo_client.js:260:18)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async addView (webpack-internal:///(rsc)/./src/app/posts.ts:56:9)
 ⨯ TypeError: Cannot read properties of undefined (reading 'close')
    at async getViews (./src/app/posts.ts:71:9)
    at async getPostDetails (./src/app/posts.ts:123:24)
    at async Page (./src/app/blog/[id]/page.tsx:31:15)
digest: "486103747"
 ⨯ MongoTopologyClosedError: Topology is closed
    at async getViews (./src/app/posts.ts:63:22)
    at async getPostDetails (./src/app/posts.ts:123:24)
    at async Page (./src/app/blog/[id]/page.tsx:31:15)
digest: "1105313916"
 ⨯ TypeError: Cannot read properties of undefined (reading 'close')
    at async getViews (./src/app/posts.ts:71:9)
    at async getPostDetails (./src/app/posts.ts:123:24)
    at async Page (./src/app/blog/[id]/page.tsx:31:15)
digest: "486103747"
 ⨯ MongoTopologyClosedError: Topology is closed
    at async getViews (./src/app/posts.ts:63:22)
    at async getPostDetails (./src/app/posts.ts:123:24)
    at async Page (./src/app/blog/[id]/page.tsx:31:15)
digest: "1105313916"

问题分析

  1. 频繁创建/关闭连接:MongoDB客户端设计为长连接复用,每次请求都调用client.connect()和client.close()会导致连接池混乱,并发请求下会出现会话过期、拓扑关闭等错误。
  2. 未初始化client的风险:如果client.connect()失败,client可能未被正确初始化,此时在finally块调用client.close()会触发Cannot read properties of undefined错误。

解决方案

1. 实现MongoDB客户端单例模式

创建lib/mongodb.ts文件,全局复用一个客户端实例:

import { MongoClient } from 'mongodb';

const uri = process.env.MONGODB_URI!;
let client: MongoClient;
let clientPromise: Promise<MongoClient>;

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

if (process.env.NODE_ENV === 'development') {
  // 开发环境下避免热重载重复创建客户端
  if (!global._mongoClientPromise) {
    client = new MongoClient(uri);
    global._mongoClientPromise = client.connect();
  }
  clientPromise = global._mongoClientPromise;
} else {
  // 生产环境直接创建单例
  client = new MongoClient(uri);
  clientPromise = client.connect();
}

export default clientPromise;

2. 修改getViews函数

使用单例客户端,不再手动关闭连接:

import clientPromise from '@/lib/mongodb';

export async function getViews(id: string) {
  const client = await clientPromise;
  const collection = client.db("views").collection("views");
  const data = await collection.findOne({ id });
  
  return data?.views || 0;
}

说明

  • 单例模式确保全局只有一个MongoDB客户端实例,连接由客户端自身维护的连接池管理,无需手动关闭。
  • 避免了并发请求下重复创建/关闭连接导致的错误,同时提升了请求性能。
  • 通过可选链操作符data?.views简化了空值判断,代码更简洁。

内容的提问来源于stack exchange,提问作者Divjot Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:37:31