【问题标题】:Is there a good way to debug a failing promise?有没有调试失败的承诺的好方法?
【发布时间】:2019-09-08 03:38:14
【问题描述】:

我在承诺的.then 块上有一个错字,承诺一直失败。我想我没有意识到是否有一种类型会转到.catch。花了很多时间才发现这是错误(一直假设它是 promise/async/etc 调用有问题。)

有没有办法让 JS 告诉我“嘿,你的 .then 块中有错误!”

代码

     searchAPI(name)
      .then(data => {
        // typo was LowerCase instead of toLowerCase
        let filtereddowndata = data
          .filter(item =>
            item.title.toLowerCase().includes(name.LowerCase())
          )
               etc etc

      })
      .catch(function() {
        console.log("no match found"); // kept going here.
      });

【问题讨论】:

  • 在 catch 回调中记录错误?
  • 关于您的问题,我似乎记得几乎不可能自动处理传递给then 的回调引发的所有错误,而不是通过catch 函数传递回调。换句话说,传递给then 函数的回调抛出的异常不会导致error 类型的事件被调度。当然,后者是由 HTML 5 指定的,而不是 ECMAScript,我目前找不到任何确认或拒绝 ECMAScript 以任何方式处理这个问题。

标签: javascript promise


【解决方案1】:

发送到.catch() 的实际错误(您在代码中忽略了它)会给您一个很好的线索,为什么会触发.catch()。使用这样的东西:

.catch(function(e) { 
    console.log(e);
    // any other processing code here
 });

我总是确保在我的 .catch() 语句中记录实际错误,这样我总能准确地看到它被触发的原因,并且不要盲目地假设代码是如何到达这里的。

这也是为什么当您没有任何 .catch() 时,node.js 将其作为控制台警告(最终导致运行时错误),因为 .then() 中内置的 try/catch 会在以下情况下对您隐藏错误你不会在.catch() 中自己暴露它们。


在这种情况下,以上内容足以为您提供精确的错误。但是在其他情况下(出于调试目的),您有时会受益于在代码的更多本地化区域周围插入自己的 try/catch 语句。这也会向您展示您的 .then() 处理程序中发生了什么。

你可以运行这个 sn-p 来查看实际的错误。

     // simulate your searchAPI() call
     function searchAPI() {
        return new Promise(resolve => {
            resolve([{title: "Superman"}, {title: "Spiderman"}]);
        });
    }
    
    let name = "Joe";
    
    searchAPI(name).then(data => {
        // typo was LowerCase instead of toLowerCase
        let filtereddowndata = data.filter(item =>
                item.title.toLowerCase().includes(name.LowerCase())
        );
    }).catch(function(e) {
        // console.log(e) will work with normal Javascript
        // here in a stackoverflow snippet where console.log has been replaced
        // you have to look at console.log(e.message) to see the error
        console.log("searchAPI failed - ", e.message);
    });

【讨论】:

    【解决方案2】:

    我只能强调@jfriend 的回答,即您应该始终使用适当的错误消息拒绝并记录它们。

    但是,了解承诺如何被拒绝以及哪些.catch() 回调将处理来自何处的拒绝也很重要。可以通过not using the traditional .then(…).catch(…) pattern 发送better differentiate error origins,甚至tag each error with the function it's coming from

    在您的情况下,错误消息“找不到匹配项”被放错了位置,因为它暗示 searchAPI 失败,而这不是到达 catch 处理程序的唯一原因。相反,更好的模式是

    function searchAPI(name) {
        …
        return Promise.reject(new Error("No match found"));
        //                              ^^^^^^^^^^^^^^^^ error message (or error code)
    }   //                              thrown exactly where the error actually occurred
    
    searchAPI(name).then(data => {
        let filtereddowndata = data.filter(item =>
            item.title.toLowerCase().includes(name.LowerCase())
        )
        …
    }, err => { // <- second `then` argument
        console.log("Error from searchAPI", err);
    });
    // would now cause an unhandled rejection about the LowerCase method call
    

    您当然可以将其与 catch 处理程序结合使用:

    searchAPI(name).then(data => {
        let filtereddowndata = data.filter(item =>
            item.title.toLowerCase().includes(name.LowerCase())
        )
        …
    }, err => { // <- second `then` argument
        console.log("Error from searchAPI", err);
    }).catch(err => {
        console.error("Error from promise callback", err);
    });
    

    【讨论】:

      猜你喜欢
      • 2013-12-12
      • 2018-07-19
      • 2022-01-24
      • 1970-01-01
      • 2021-06-29
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 2015-04-13
      相关资源
      最近更新 更多