【问题标题】:How to Pass MongoDB error to React from Express如何将 MongoDB 错误从 Express 传递给 React
【发布时间】:2019-04-13 04:08:02
【问题描述】:

我正在使用 MERN 应用程序。在我的 express.js 模型之一中,我有独特的电子邮件架构,如下所示

email: {
   type: String,
   trim: true,
   required: true,
   minlength: 3,
   unique: true
},

当我保存如下记录时,我正在检查电子邮件地址的唯一性

address.save()
.then(address => {
   //other code
})
.catch(err => {
   console.log(err);
   res.status(500).json({
     message: 'Error Occured',
         error: err
   });
 });

我在终端中遇到错误。

{ MongoError: E11000 duplicate key error collection: addresses.addresses index: email_1 dup key: { : "nowphp@yahoo.com" }
[0]     at Function.create (/home/foysal/Videos/my-app/node_modules/mongodb-core/lib/error.js:43:12)
[0]     at toError (/home/foysal/Videos/my-app/node_modules/mongodb/lib/utils.js:149:22)
[0]     at coll.s.topology.insert (/home/foysal/Videos/my-app/node_modules/mongodb/lib/operations/collection_ops.js:859:39)
[0]     at /home/foysal/Videos/my-app/node_modules/mongodb-core/lib/connection/pool.js:532:18
[0]     at process._tickCallback (internal/process/next_tick.js:61:11)
[0]   driver: true,
[0]   name: 'MongoError',
[0]   index: 0,
[0]   code: 11000,
[0]   errmsg:
[0]    'E11000 duplicate key error collection: addresses.addresses index: email_1 dup key: { : "nowphp@yahoo.com" }',
[0]   [Symbol(mongoErrorContextSymbol)]: {} }

我想将此错误 errmsg: 'E11000 duplicate key error collection: addresses.addresses index: email_1 dup key: { : "nowphp@yahoo.com" }', 修改为 Email already Exists 并将其传递给 React(前端)。

我该怎么做?

更新

我在express.js中使用下面的代码

address.save()
    .then( address => {
        // others code
    })
    .catch( err => {
        const errString = err.toString();
        if (errString.includes("E11000")) return res.status(404).json({ err: 'That email is already in use!' });
    });

我的 React Redux 操作如下所示

export const addAddress = value => dispatch => {
  return Axios.post('/api/address', value)
    .then( response => {
      // other code
    })
    .catch( error => {
      console.log('actionError', error )
    });
};

我在控制台中遇到以下错误

Error: "Request failed with status code 404"

【问题讨论】:

    标签: node.js reactjs mongodb express


    【解决方案1】:

    您有两个选择:在创建之前检查电子邮件是否已经存在(更好的选择)或允许 Mongo 在用户创建期间抛出 error object,将其转换为 string,然后检查 string 是否包含 @ 987654337@.

    工作示例https://github.com/mattcarlotta/fullstack-mern-kit(点击here查看正在使用的代码,如下所述;另外,下面的代码引用了一个User静态方法,你可以找到here )


    例如(选择一个选项,你不需要两个):

    const createUser = async (req, res, done) => {
      const {
        email,
        firstName,
        lastName,
        userName,
        backgroundInfo,
        address,
      } = req.body;
    
      if (
        !email
        || !firstName
        || !lastName
        || !userName
        || !backgroundInfo
        || isEmpty(address)
      ) return res.status(400).json({ err: “You must include all required fields to create a new user!” }); // checking if the req.body contains all the required user fields
    
      try {
        const emailTaken = await User.findOne({ email });
        if (emailTaken) return res.status(400).json({ err: “That email is already in use!" }); // checking if the user exists before creation
    
        await User.createUser(req.body); // createUser is a custom static method placed on the model
    
        res
          .status(201)
          .json({ message: `Successfully created ${req.body.userName}.` });
      } catch (err) {
        const errString = err.toString();
    
        if (errString.includes("E11000")) return res.status(400).json({ err: “That email is already in use!" }); // handling the error Mongo throws if the user exists during creation
    
        return res.status(400).json({ err: errString }); // handling any other misc errors
      }
    };
    

    默认情况下axios 不会从服务器返回任何错误。相反,您将不得不创建一个自定义 axios 配置:axiosConfig.js。此配置最重要的部分是更改错误interceptor,如here 所示。这是专门寻找来自error.response.data.err 的错误。如果您不将err 用于API,那么您需要更新此line

    这个line 的目的是检查error.response.data.err 是否存在,如果不存在,则返回一个通用的Network Error (error.message) 消息。

    创建此配置后,您现在需要将其用于整个应用程序 (import axios from '../path/to/axiosConfig')。

    注意:请将baseURL 更新为您的API localhost,它是port。使用此配置的好处是,您使用axios 进行的任何调用都将在前面加上http://localhost:port/

    例如,而不是:

    axios.get("http://localhost:5000/api/user")

    会是:

    axios.get("user")

    如果您有任何问题,请在提问之前参考上面的 github 存储库,因为它显示了如何集成所有内容。如果您打算在生产中使用它,则需要使用ENVs(此示例使用better-npm-run 包,但您可以使用cross-envdotenv)。

    【讨论】:

    • 感谢@Matt Carlotta 的详细回复。我应用了您的解决方案,但出现错误。我更新了我的问题。你可以在那里看到。谢谢。
    • 如果您使用的是axios,那么您需要自定义axios 配置来更改interceptor。不幸的是,它默认吐出一个通用错误而不是服务器返回的错误。不过,我已经更新了答案以包括如何完成此操作(位于底部)。
    • 感谢@Matt Carlotta 的详细回复。我可以像这样使用你的例子吗? github.com/afoysal/mern/blob/master/client/src/store/actions/…
    • 可以,但如果您打算在其他components 和/或actions 中重用axios 配置,最好将其与actions 分开。否则,它就可以了。
    • 感谢@Matt Carlotta。您的解决方案正在运行。谢谢。
    【解决方案2】:

    好吧,如果您查看正在记录的 Error 对象,您可以观察到一些类似 code 属性的内容。

    您可以评估此​​类属性,如果是这种情况,只需传递适当的自定义错误消息。

    address.save()
    .then(address => {
       //other code
    })
    .catch(err => {
       const {code} = err
       console.log(err);
       if (code === 11000) {
         err = new Error('Email already Exists');
       }
       res.status(500).json({
         message: 'Error Occured',
         error: err
       });
     });
    

    【讨论】:

    • 谢谢@diegoaguilar。但是可以修改'E11000 duplicate key error collection: addresses.addresses index: email_1 dup key: { : "nowphp@yahoo.com" }', [0] [Symbol(mongoErrorContextSymbol)]: {} }吗?
    • 谢谢@diegoaguilar。您的解决方案不起作用。我在控制台中收到Error: "Request failed with status code 500"。谢谢。
    • 这是您捕获和记录错误的一种方式。查看网络详情
    • 感谢@diegoaguilar 的评论。我更新了我的问题。
    猜你喜欢
    • 2018-11-16
    • 2023-02-09
    • 1970-01-01
    • 2023-03-27
    • 2019-08-25
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多