首页 > 解决方案 > 从 mongoose 唯一索引中捕获重复错误并发送 res 409

问题描述

我有一个猫鼬模式,我将电子邮件定义为唯一的。当我插入重复的电子邮件时,我收到了 Mongoose 错误,这是我所期望的,但我想抓住它并在发生这种情况时发送 res.status(409),但我做不到。

我尝试使用mongoose-beautiful-unique-validation库来更改收到的错误并捕获它,但我仍然迷路了。

我的架构:

'use strict';
const beautifyUnique = require('mongoose-beautiful-unique-validation');

const mongoose = require('mongoose');

// create the schema

const { Schema } = mongoose;

const accountSchema = new Schema({
    uuid: {
        type: String,
        unique: true,
      },
      email: {
        type: String,
        unique: 'This email is already taken ({VALUE})',
      },
    password: String,
    createdAt: Date, 
    verification: {
      verificationCode: String,
      verifiedAt: Date,
    },
  });

accountSchema.plugin(beautifyUnique);
const Account = mongoose.model('Account', accountSchema);

module.exports = Account;

我试图捕捉的错误:


{ ValidationError: Validation failed
    at ValidationError.inspect (/home/danielromero/Desktop/foodtrack git clone/foodtrack-demo/backend_foodtrack/node_modules/mongoose/lib/error/validation.js:59:24)
    at formatValue (internal/util/inspect.js:453:31)
    at inspect (internal/util/inspect.js:193:10)
    at Object.formatWithOptions (util.js:165:18)
    at Console.(anonymous function) (console.js:188:15)
    at Console.log (console.js:199:31)
    at insertAccountIntoDatabase (/home/danielromero/Desktop/foodtrack git clone/foodtrack-demo/backend_foodtrack/webserver/controllers/account/create-account.js:36:13)
    at process._tickCallback (internal/process/next_tick.js:68:7)
  errors:
   { email:
      { ValidatorError: This email is already taken (sapo@yopmail.com)
          at new ValidatorError (/home/danielromero/Desktop/foodtrack git clone/foodtrack-demo/backend_foodtrack/node_modules/mongoose/lib/error/validator.js:29:11)
          at /home/danielromero/Desktop/foodtrack git clone/foodtrack-demo/backend_foodtrack/node_modules/mongoose-beautiful-unique-validation/index.js:150:39
          at Array.forEach (<anonymous>)
          at /home/danielromero/Desktop/foodtrack git clone/foodtrack-demo/backend_foodtrack/node_modules/mongoose-beautiful-unique-validation/index.js:140:36
          at process._tickCallback (internal/process/next_tick.js:68:7)
        message: 'This email is already taken (sapo@yopmail.com)',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'unique',
        path: 'email',
        value: 'sapo@yopmail.com',
        reason: undefined } },
  _message: 'Validation failed',
  name: 'ValidationError' }

我只想知道如何引用 ValidationError 消息,并在中间件中告诉我的代码,当这种情况发生时,它必须发送 409 响应。

标签: javascriptnode.jsmongodbmongoose

解决方案


如果您查看堆栈跟踪,您可以看到错误被抛出的位置at insertAccountIntoDatabase (/home/danielromero/Desktop/foodtrack git clone/foodtrack-demo/backend_foodtrack/webserver/controllers/account/create-account.js:36:13))

您需要通过代码(可能在您的资源中)将抛出的错误转换为适当的响应来捕获该错误。它可能看起来模糊地像:

try {
  await Account.create(params);
} catch (err) {
  // You only want to catch errors that you know how to handle
  if (err.ValidationError) return res.status(409).send();
  // hopefully this will get caught by something in your middleware and turned into a 500 with helpful metrics & logging
  throw err;
}

从概念上讲,您希望在错误发生时捕获错误——您共享的代码配置了 mongoose 模式的行为方式,但您希望修改使用它的地方。


推荐阅读