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

MongoDB+Express服务报错:Cannot read properties of undefined (reading 'collection')

问题:MongoDB连接后db对象未定义导致接口报错

错误信息

访问http://localhost:3600/artifacts时触发以下错误:

TypeError: Cannot read properties of undefined (reading 'collection')
    at /home/gatwiri/MEAN/sbom-dataserver.js:41:6
    at Layer.handle [as handle_request] (/home/gatwiri/MEAN/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/gatwiri/MEAN/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/home/gatwiri/MEAN/node_modules/express/lib/router/route.js:114:3)
    at Layer.handle [as handle_request] (/home/gatwiri/MEAN/node_modules/express/lib/router/layer.js:95:5)
    at /home/gatwiri/MEAN/node_modules/express/lib/router/index.js:284:15
    at param (/home/gatwiri/MEAN/node_modules/express/lib/router/index.js:365:14)
    at param (/home/gatwiri/MEAN/node_modules/express/lib/router/index.js:376:14)
    at Function.process_params (/home/gatwiri/MEAN/node_modules/express/lib/router/index.js:421:3)
    at next (/home/gatwiri/MEAN/node_modules/express/lib/router/index.js:280:10)

控制台输出:

GEThttp://localhost:3600/artifacts
[HTTP/1.1 500 Internal Server Error 1ms]

Content Security Policy: The page’s settings blocked the loading of a resource at http://localhost:3600/favicon.ico ("default-src").

问题代码

const express = require('express')
const app = express()
var db
const dbName = 'my-test'
const port = 3600
let table = 'artifact'
const url = "mongodb://localhost:27017/"

app.listen(port, function() {
  console.log('Listening on ' + port + '.')
})

const MongoClient = require('mongodb').MongoClient

app.route('/').get((req, res) => {
  res.send("Recognized endpoints on this server include '/artifacts' and '/artifacts/NAME'.")
})
app.route('/artifacts').get((req, res) => {
  db.collection(table).find().toArray((err, artifact) => {
    if (err) throw err
    var artifacts = []
    artifact.forEach((value) => {
      artifacts.push({scriptname: value.scriptname})
    })
    res.send(artifacts)
  })
})
app.route('/artifacts/:scriptname').get((req, res) => {
  const scriptname = req.params['scriptname']
  db.collection(table).findOne({scriptname: scriptname}, function(err, artifact) {
  if (err) throw err
    res.send({
      scriptname: artifact.scriptname,
      version: artifact.version,
      cdn: artifact.cdn
    })
  })
})

MongoClient.connect(url, (err, client) => {
  const db = client.db(dbName);
  db.collection(table).find().toArray((err, artifact) => {
        if (err) throw err
        artifact.forEach((value) => {
    })
    client.close()
  })
})

问题根源

  1. 全局db变量未正确赋值:在MongoClient.connect回调中使用const db声明了局部变量,覆盖了全局的db,导致全局db始终为undefined,接口调用时自然无法读取collection属性。
  2. 连接后立即关闭客户端:回调中执行了client.close(),关闭了MongoDB连接,即使db赋值成功,后续请求也无法操作数据库。
  3. 服务启动早于数据库连接:app.listen在数据库连接前执行,可能出现请求到达时数据库还未完成连接的情况。

修复后的代码

const express = require('express')
const app = express()
var db
const dbName = 'my-test'
const port = 3600
let table = 'artifact'
const url = "mongodb://localhost:27017/"

const MongoClient = require('mongodb').MongoClient

// 先配置路由
app.route('/').get((req, res) => {
  res.send("Recognized endpoints on this server include '/artifacts' and '/artifacts/NAME'.")
})
app.route('/artifacts').get((req, res) => {
  db.collection(table).find().toArray((err, artifacts) => {
    if (err) {
      console.error(err);
      return res.status(500).send('Database error');
    }
    const result = artifacts.map(value => ({ scriptname: value.scriptname }))
    res.send(result)
  })
})
app.route('/artifacts/:scriptname').get((req, res) => {
  const scriptname = req.params['scriptname']
  db.collection(table).findOne({ scriptname: scriptname }, function(err, artifact) {
    if (err) {
      console.error(err);
      return res.status(500).send('Database error');
    }
    if (!artifact) {
      return res.status(404).send('Artifact not found');
    }
    res.send({
      scriptname: artifact.scriptname,
      version: artifact.version,
      cdn: artifact.cdn
    })
  })
})

// 连接数据库成功后再启动服务
MongoClient.connect(url, (err, client) => {
  if (err) {
    console.error('Failed to connect to MongoDB:', err);
    process.exit(1);
  }
  // 给全局db赋值,不要用const声明局部变量
  db = client.db(dbName);
  console.log('Connected to MongoDB successfully');
  
  // 数据库连接成功后启动服务
  app.listen(port, function() {
    console.log('Listening on port ' + port + '.')
  })
})

关键修改说明

  • 移除回调中db的const声明,直接给全局db变量赋值,确保接口能访问到数据库实例。
  • 删除client.close(),保持MongoDB连接长期有效,供后续请求复用。
  • 将app.listen移到数据库连接成功的回调中,确保服务启动时数据库已就绪。
  • 增加错误处理逻辑,避免直接throw err导致服务崩溃,返回合适的HTTP状态码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:36:29