【问题标题】:Nodejs Promise reject wont forward error messagesNodejs Promise 拒绝不会转发错误消息
【发布时间】:2019-12-27 01:22:16
【问题描述】:

我试图捕捉一个错误,指出我试图读取的文件不存在。我故意将文件命名错误。

在我的控制器内部我有getAllProducts(),它将返回一个承诺,如果承诺解决了,那么我会渲染一个页面,如果没有,则将错误显示到控制台

// inside productController.js 
exports.getProductForShop = (req, res, next) => {
    productModel.getAllProducts()
        .then(products => {
            res.render('shop', {
                title: 'shop',
                products,
                path: '/'
            });
        })
        .catch((error) => {
            console.log(error);
        });
}

在我的模型类中,我已经实现了上面提到的函数,即:getAllProducts()这里的代码是一个静态函数,如果这很重要的话

// inside productModel.js
static getAllProducts() {
    return new Promise((resolve, reject) => {
        fs.readFile('data/wrongName.json', (error, products) => { // wrong file name
            if (error) {
                reject(new Error(error)); // <-- line that sends error message
            }

            resolve(JSON.parse(products)); // this is line 52, it should not be executed
        })
    })
}

当我运行代码时,我收到以下错误消息

SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
    at ReadFileContext.callback (C:\Users\user\Desktop\JS\NodeJs\models\productModel.js:52:30)
?[90m    at FSReqCallback.readFileAfterOpen [as oncomplete] (fs.js:239:13)?[39m

这一定意味着fs.readFile 收到了错误的文件名,抛出了一个错误,reject(new Error(error)); 被调用,仍然继续执行包含resolve(); 的第 52 行

当我在控制台记录 if(error) 块内的错误时,我得到正确的错误消息

Error: Error: ENOENT: no such file or directory, open 'C:\Users\user\Desktop\JS\NodeJs\data\wrongName.json'
    at ReadFileContext.callback (C:\Users\user\Desktop\JS\NodeJs\models\productModel.js:49:35)
    at FSReqCallback.readFileAfterOpen [as oncomplete] (fs.js:239:13)

当我执行return reject(new Error(error)); 时,我得到正确的错误信息,如上所示。

有人可以向我解释为什么传递给reject(new Error(error)); 的错误消息没有被catch 块捕获吗?

更新: 添加 catch 块也不起作用,似乎 return render 是唯一的方法?!我的印象是拒绝将承诺置于拒绝状态并阻止进一步执行

// inside productModel.js
static getAllProducts() {
    return new Promise((resolve, reject) => {
        fs.readFile('data/productseData.json', (error, products) => {
            if (error) {
                reject(new Error(error));
            }

            resolve(JSON.parse(products));
        })
    }).catch((error) => {
        console.log(error);
    })
}

【问题讨论】:

  • 那么添加return reject之后有什么问题呢?或者你是在问为什么它不能正常工作
  • @aw04 是的,它应该可以工作 without return reject 因为拒绝调用会将承诺置于拒绝状态并阻止进一步执行
  • 这是reject(error),而不是reject(new Error(error))。 (是的,你应该在拒绝后返回。不,如果没有return,它不一定能工作——执行会继续,尽管承诺的状态不能改变。)
  • 或者,在 else 块中解决,然后你不需要返回 - 问题是目前的代码正在尝试 JSON.parse(undefined) 因为结果很可能是 undefined 如果有一个错误

标签: javascript node.js express es6-promise


【解决方案1】:

您对这里发生的事情有一点误解。调用reject 会拒绝这个promise,后面的resolve 也不会解决它。到目前为止,一切都很好。问题是如果没有return,它不会停止执行。因此,您实际上是在运行不必要的代码,而这恰好会导致错误。

你应该确保resolve代码在出错的情况下不会被执行。您可以使用return reject 或将resolve 包装在else 块中来完成此操作。

请记住,resolve/reject 没有什么特别之处。它们是简单的函数调用,函数调用不会停止执行。

【讨论】:

  • 如果出现错误,产品将不会是您可以 JSON.parse 的任何东西,这会引发错误
  • 就像在 else 块中解析一样:p 这就是我要做的
猜你喜欢
  • 2022-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 2012-11-08
  • 1970-01-01
相关资源
最近更新 更多