【问题标题】:Unhandled Error returned in Promise Rejection (Typescript)在 Promise Rejection (Typescript) 中返回未处理的错误
【发布时间】:2020-06-12 05:42:50
【问题描述】:

所以,在使用 Promise 方面,我并不是很新。我了解并且之前使用过.then(), .catch(), Promise.all()。我主要用它们来获取 API 调用。

但是,在创建自己的承诺方面,我是一个完全的初学者。

所以,我试图创建自己的承诺,reject() 函数不断给我unhandled error (my rejection message) 消息。虽然,resolve() 函数按预期工作。

这是我的(简化)代码:

const request = require('request-promise');

return new Promise(async (resolve, reject) => {
    try {
        /*
         * Some other codes that might throw other exceptions
         */
        ....
        ....

        const options = "ASSUME THIS IS A CALL TO A THIRD-PARTY API";

        await request(options)
            .then((val: any) => {
                ...
                // I had no issue with this. Resolve returns properly
                resolve(val);                     
            })
            .catch((e: any) => {
                ...

                // I would need to translate the error message from this 
                // Third-Party API. But, this reject function keeps on 
                // returning me an "unhandled error" issue
                reject(translateMsg(e.message, "fr"));
            });
    }
    catch(err) {
        reject("Oops other errors detected");
    }
}

注意:此错误消息显示在我的 Firebase 函数日志中。我不确定问题出在我的代码还是其他地方。

谢谢!

(编辑 1) 我在request.catch() 语句中做了一些其他的处理(翻译等)。所以,我需要返回一个新的错误消息,而不是默认的 e 对象。

(编辑 2) 假设translateMsg() 已经过良好测试并且它总是返回一个字符串。

【问题讨论】:

  • 这里request 已经返回了一个承诺。你为什么要在另一个 Promise 上创建 Promise?
  • 无论使用什么你创建的这个承诺显然都不能处理拒绝......?
  • @palaѕн 实际上,为了简洁起见,我没有在此处粘贴一些代码。所以,request.then() request.catch() 中还有一些其他的代码。我试图处理请求的结果并返回一个新的 Promise
  • @deceze 我将这个 npm 包 (npmjs.com/package/request-promise) 用于request(),根据文档,它确实可以处理拒绝。

标签: javascript typescript promise


【解决方案1】:

如果您的 API 已经返回一个承诺,那么绝对没有理由创建您自己的承诺。只需使用您拥有的那个。此外,很少建议将 async/await 与 then/catch 混合使用。

老实说,最好的做法是根本不添加任何内容。只需return request(options),调用者将收到并承诺已经自行解决或拒绝。

如果您绝对必须在解决或拒绝方面更改呼叫接收的内容,您正在做的事情可以简化为:

const options = "ASSUME THIS TO BE AN API CALL";
try {
    const val = await request(options)
    // maybe you want to change val here?  Return what you want.
    return val
}
catch (err) {
    throw "Oops other errors detected"
}

【讨论】:

  • 非常感谢您的回复!我上面给出的代码 sn-p 可能过于简化了。最外面的 try-catch 块用于捕获const options 上方的代码引发的其他错误。内部的 catch 块是从我无权访问的第三方 API 中捕获该错误。我需要返回翻译后的错误消息,而不是该 API 调用的原始错误消息。我想我只需将我的 request(option) 代码移动到另一个异步函数,我可以从这里调用它。那样的话,我的代码会更易读。
  • 无论如何,感谢您指出“将 async/await 与 then/catch 混合”是一种反模式,在重新访问 Firebase 函数文档 (firebase.google.com/docs/functions/callable) 后,我才意识到 Firebase 中的错误应该是以这种方式返回throw new functions.https.HttpsError("")。正如您指出的一些最佳做法,我仍会将其标记为已接受的答案。
  • 如果您在问题中显示整个函数会更清楚,尤其是您使用的是可调用类型函数这一事实。并非所有类型的函数都以相同的方式工作。 stackoverflow.com/help/minimal-reproducible-example
【解决方案2】:

首先,感谢大家在处理 Promise 时指出所有最佳实践。我将相应地修复我的代码。

我的问题原来源于我使用的 Google Firebase 功能

重新查看文档后,我意识到在 Firebase 函数中处理错误的正确方法是抛出 throw new functions.https.HttpsError("") 而不是 Promise.reject()

再次感谢!

来源:https://firebase.google.com/docs/functions/callable

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    • 2019-11-10
    • 1970-01-01
    • 2017-07-25
    相关资源
    最近更新 更多