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

使用curl提交评论时触发TypeError:无法读取undefined的insertOne属性

问题:调用curl添加评论时触发TypeError: Cannot read properties of undefined (reading 'insertOne')

使用以下curl命令提交评论时出现错误:

curl -X POST http://localhost:4444/api/v1/reviews/new -H "Content-Type:application/json" -d '{"movieId":12,"user":"sara","review":"good"}'

报错信息:

TypeError: Cannot read properties of undefined (reading 'insertOne')

相关代码文件

reviews.controller.js

import reviewsDAO from "../dao/reviewsDAO.js";

export default class ReviewsController{

  static async apiPostReview(req, res, next) {
    try {
      const movieId = parseInt(req.body.movieId)
      const review = req.body.review
      const user = req.body.user
      console.log('movieId', movieId)
      const reviewResponse = await reviewsDAO.addReview(
        movieId,
        user,
        review
      )
      res.json({ status: "success" })
    } catch (e) {
      res.status(500).json({ error: e.message })
    }
  }

  static async apiGetReview(req, res, next) {
    try {
      let id = req.params.id || {}
      let review = await reviewsDAO.getReview(id)
      if (!review) {
        res.status(404).json({ error: "Not found" })
        return
      }
      res.json(review)
    } catch (e) {
      console.log(`api, ${e}`)
      res.status(500).json({ error: e })
    }
  }

  static async apiUpdateReview(req, res, next) {
    try {
      const reviewId = req.params.id
      const review = req.body.review
      const user = req.body.user

      const reviewResponse = await reviewsDAO.updateReview(
        reviewId,
        user,
        review
      )

      var { error } = reviewResponse
      if (error) {
        res.status(400).json({ error })
      }

      if (reviewResponse.modifiedCount === 0) {
        throw new Error(
          "unable to update review",
        )
      }

      res.json({ status: "success" })
    } catch (e) {
      res.status(500).json({ error: e.message })
    }
  }

  static async apiDeleteReview(req, res, next) {
    try {
      const reviewId = req.params.id
      const reviewResponse = await reviewsDAO.deleteReview(reviewId)
      res.json({ status: "success" })
    } catch (e) {
      res.status(500).json({ error: e.message })
    }
  }

  static async apiGetReviews(req, res, next) {
    try {
      let id = req.params.id || {}
      let reviews = await reviewsDAO.getReviewsByMovieId(id)
      if (!reviews) {
        res.status(404).json({ error: "Not found" })
        return
      }
      res.json(reviews)
    } catch (e) {
      console.log(`api, ${e}`)
      res.status(500).json({ error: e })
    }
  }
}

reviewsDAO.js

import mongodb from 'mongodb';
const ObjectID=mongodb.ObjectID;

let reviews;

export default class ReviewsDAO{
    static async injectDB(conn){
        if(reviews){
            return
        }
        try{
            reviews = await conn.db("reviews").collection("reviews");
        } catch(e){
            console.error(`Unable to establish collection handles in userDAO: ${e}..`);
        };
    };

    static async addReview(movieId,user,review){
        try{
            const reviewDoc={
                movieId:movieId,
                user:user,
                review:review
            }
            return await reviews.insertOne(reviewDoc);
        }catch(e){
            console.error(`Unable to post review: ${e}`);
            return{error:e};
        };
    };

    static async getReview(reviewId){
        try{
            return await reviews.findOne({_id:ObjectID(reviewId)})
        }catch(e){
            console.error(`Unable to get review: ${e}`);
            return{error:e};
        };
    };

    static async updateReview(reviewId,user,review){
        try{
            const updateResponse=await review.updateOne({_id:ObjectID(reviewId)}, 
            {$set:{user:user,review:review}});
            return updateResponse;
        }catch(e){
            console.error(`Unable to update review: ${e}`);
            return{error:e};
        };
    };

    static async getReviewByMovieId(movieId){
        try{
            const cursor=await reviews.find({movieId: parseInt(movieId)});
            return cursor.toArray();
           
        }catch(e){
            console.error(`Unable to get review: ${e}`);
            return{error:e};
        };
    };
};

reviews.route.js

import express from 'express';
import ReviewsCtrl from "./reviews.controller.js";

const router=express.Router();

router.route("/movie/:id").get(ReviewsCtrl.apiGetReviews);
router.route("/new").post(ReviewsCtrl.apiPostReview);
router.route("/:id")
    .get(ReviewsCtrl.apiGetReviews)
    .put(ReviewsCtrl.apiUpdateReview)
    .delete(ReviewsCtrl.apiDeleteReview)

export default router;

moviedb.js

import app from './server.js';
import ReviewsDAO from "./dao/reviewsDAO.js";
import mongodb from 'mongodb';
import dotenv from 'dotenv';

const MongoClient=mongodb.MongoClient

dotenv.config();
const mongo_username = process.env.MONGO_USERNAME;
const mongo_password = process.env.MONGO_PASSWORD;

const port=4444;

MongoClient.connect(`mongodb+srv://${mongo_username}:${mongo_password}@cluster0.b5f7prn.mongodb.net/test`,
{
  maxPoolSize: 50,
  wtimeoutMS: 2500,
  useNewUrlParser: true
})
.catch(err => {
    console.error(err.stack)
    console.error("Error connecting to the database:", err.message)
    process.exit(1)
  })
.then(async client => {
    await ReviewsDAO.injectDB(client)
    app.listen(port, () => {
      console.log(`listening on port ${port}`)
    })
  })

问题分析与修复方案

核心错误原因

TypeError: Cannot read properties of undefined (reading 'insertOne') 说明调用reviews.insertOne()时,reviews变量是undefined,即MongoDB集合未被正确初始化。

具体修复点

  1. 匹配数据库连接目标
    在moviedb.js的连接字符串中指定的数据库是test,但reviewsDAO.js的injectDB方法尝试连接reviews数据库。需确保目标数据库存在,或修改injectDB方法匹配连接字符串中的数据库:

    static async injectDB(conn){
        if(reviews){
            return
        }
        try{
            // 改为连接test库,或确保reviews库已创建
            reviews = await conn.db("test").collection("reviews");
        } catch(e){
            // 修正日志中的DAO名称(原userDAO应为reviewsDAO)
            console.error(`Unable to establish collection handles in reviewsDAO: ${e}..`);
        };
    };
    
  2. 修复updateReview方法的变量名错误
    updateReview中误写为review.updateOne,应该是reviews.updateOne(缺少复数s):

    static async updateReview(reviewId,user,review){
        try{
            const updateResponse=await reviews.updateOne({_id:ObjectID(reviewId)}, 
            {$set:{user:user,review:review}});
            return updateResponse;
        }catch(e){
            console.error(`Unable to update review: ${e}`);
            return{error:e};
        };
    };
    
  3. 统一方法名匹配
    reviews.controller.js中调用reviewsDAO.getReviewsByMovieId,但reviewsDAO.js中的方法名是getReviewByMovieId(缺少复数s),需统一方法名:

    // reviewsDAO.js中修改方法名
    static async getReviewsByMovieId(movieId){
        try{
            const cursor=await reviews.find({movieId: parseInt(movieId)});
            return cursor.toArray();
           
        }catch(e){
            console.error(`Unable to get reviews: ${e}`);
            return{error:e};
        };
    };
    
  4. 补充缺失的deleteReview方法
    reviews.controller.js中调用了reviewsDAO.deleteReview,但DAO文件中未实现该方法,需补充:

    // reviewsDAO.js中添加
    static async deleteReview(reviewId){
        try{
            const deleteResponse=await reviews.deleteOne({_id:ObjectID(reviewId)});
            return deleteResponse;
        }catch(e){
            console.error(`Unable to delete review: ${e}`);
            return{error:e};
        };
    };
    

完成以上修复后,重启服务再执行curl命令,即可正常提交评论。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:46:01