id 错误时 Nodejs Express 崩溃

Nodejs Express crash when id was wrong

我正在使用 Nodejs、Express、Mongoose 开发 REST 服务。我还在学习阶段。

我有一个问题。

例如,当我尝试使用ID 拉取内容时,如果ID 正确且对应,则可以正常工作。但如果 ID 不正确或丢失或超过 24 个字符,则问题是服务崩溃。如果收到 24 个字符的 ID,我可以 return 404 并且服务不会崩溃。我怎样才能避免这个崩溃问题。

正确请求(返回结果为JSON):http://localhost:8080/api/v1/posts?id=615ccb9f89a5e20454306090

崩溃请求:http://localhost:8080/api/v1/posts?id=123

错误:

events.js:366
    throw err; // Unhandled 'error' event
    ^

Error [ERR_UNHANDLED_ERROR]: Unhandled error. ({ status: 500, error: 'Post not found' })
    at Function.emit (events.js:364:17)
    at D:\CMS\node_modules\mongoose\lib\model.js:4872:15
    at processTicksAndRejections (internal/process/task_queues.js:77:11) {
  code: 'ERR_UNHANDLED_ERROR',
  context: { status: 500, error: 'Post not found' }
}
[nodemon] app crashed - waiting for file changes before starting...

控制器层:

...
function get(req, res) {
    postService
        .get(req)
        .then((result) => result && res.status(200).json(result))
        .catch((e) => errorMessages(e, res));
}

服务层:

...
async function get(req) {
    const findParams = {};
    if (req.query.id) {
        findParams['_id'] = req.query.id.trim().substring(0, 24);
    }
    const post = await Posts.find(findParams, (e, post) => {
        if (e) throw { status: 500, error: `Post not found` };
        return post;
    }).sort({ createdDate: -1 });
    if (req.query.id && post[0]) {
        return { ...post[0]._doc };
    }
    return post;
}

Post 型号:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const schema = new Schema({
    title: { type: String, unique: true, required: true, minlength: 1, maxlength: 64 },
    meta: {
        lang: { type: String, minlength: 2, maxlength: 2, default: 'en' },
        distribution: { type: String, minlength: 1, maxlength: 64, default: 'global' },
        robots: { type: String, minlength: 1, maxlength: 64, default: 'index,follow' },
        author: { type: String, minlength: 1, maxlength: 64 },
        description: { type: String, minlength: 1, maxlength: 256 },
        keywords: { type: String, minlength: 1, maxlength: 256 },
        canonical: { type: String, minlength: 1, maxlength: 512 },
        others: { type: [Schema.Types.Mixed], default: [] },
    },
    coverImage: { type: String, minlength: 1, maxlength: 1024 },
    summary: { type: String, required: true, minlength: 1, maxlength: 1024 },
    body: { type: [Schema.Types.Mixed], default: [] },
    slug: { type: String, unique: true, required: true, minlength: 1, maxlength: 1024 },
    createdDate: { type: Date, required: true, default: Date.now },
    status: { type: Boolean, required: true, default: true },
    categories: [{ type: String, minlength: 1, maxlength: 32 }],
    like: { type: Number, default: 0 },
    dislike: { type: Number, default: 0 },
});

module.exports = mongoose.model('Posts', schema);

如何防止服务崩溃或是否有需要修复的代码?谢谢

您可以在发送查询之前检查提供的字符串是否是有效的 MongoDB ID:

var ObjectId = require('mongoose').Types.ObjectId;

async function get(req) {
    
    if (!ObjectId.isValid(req.query.id)){
        throw { status: 400, error: `Invalid ID` }
    }

    ...
}
const post = await Posts.find(findParams, (e, post) => {
    if (e) throw { status: 500, error: `Post not found` };
    return post;
}).sort({ createdDate: -1 });

这很奇怪。如果您正在使用 await,则不要传递回调。只是 try/catch 围绕这个,它会捕获错误。