ts 使用 async 异步方法时,内部的逻辑错误在creator 编辑器中无法抛出,且会打断错误逻辑之后的所有逻辑!

  • Creator 版本: 2.4.0

  • 目标平台: creator 模拟器

  • 重现方式:可使用下面贴的代码测试

  • 重现概率: 100%

onLoad () {
    this.testScript()
}

async testScript(){
    cc.log("bg1 = ", typeof bg)

    // 该处为错误逻辑,如果注释掉此处,则 testPromise 中的错误可以正常抛出;反之则直接断开
    let bg = this.node.getChildByName("bgbgbg").getComponent(cc.Sprite)
    cc.log("bg2 = ", typeof bg)

    let a = await this.testPromise("111").then(a => a).catch(error => error)
    cc.log("a = ", a)
}

testPromise(str:string){
    let ret = new Promise((resolve,reject) =>{
        setTimeout(() => {
            let bg = this.node.getChildByName("bgbgbg").getComponent(cc.Sprite)
            cc.log("bg2 = ", typeof bg)
            resolve(str)
        }, 1000)
    })
    return ret   
}

不知道你想表达什么,我试了你的代码,抛出错误的行为表现是正常的

  1. async函数本身返回的是一个新的promise,和内部的testPromise无关;
  2. promise内部的代码执行是同步的,所以在testPromise被new出来之前的错误( let bg = … )会中断后续的逻辑;
  3. 你的async函数内部没有try-catch,外部调用的地方也没有promise.catch,错误会直接往上抛;

我这边测试的时候,红框内的逻辑实际是错误的(没有 bgbgbg 这个节点),应该在编辑器中报错,但实际没有报错,且红框之后的逻辑也都被打断了,不会再有任何输出或报错的

那肯定的啊,你这里报错,后面就没法执行了啊

但实际红框中的报错也没有在编辑器中输出,运行的时候只是停住了,不便于定位问题
上面逻辑运行之后,控制台只有如下图的信息,

原生上,是会出现报错日志不显示出来,已经提交处理了。

感谢反馈,可以参考下这个修复
https://github.com/cocos-creator/engine/pull/7127

是否测试过可行吗?我这边实测无效啊!强调一下不是 Promise 中的错误哈!

一样的,async 最终在 polyfill 中也是 promise 实现,之前的修复不能解决根本问题,可以参考下这两个修复
修复将进入 2.4.3

https://github.com/cocos-creator/cocos2d-x-lite/pull/2691

https://github.com/cocos-creator-packages/jsb-adapter/pull/328

刚测试了这两个修复,也是不生效的,你们是否测试过可行呢?
而且截图中的这个方法有被复写的嫌疑,会影响之后 bugly 的错误上传!:sweat:

修改之后,模拟器可能需要编译一下, 才能在 v8 调试界面的 console tab 下输出错误信息
可以参考 Build simulator 部分
https://github.com/cocos-creator/cocos2d-x-lite/blob/develop/README.md

编译过了的,但确定是不生效的。如果没编译,jsb.onError 方法会直接报错找不到。
还有就是确定不考虑方法被复写的方面吗?

目前确实会有被多次注册覆盖的问题,我们记录的新的 issue,之后解决

这边测试是会输出异常的,不过只是输出错误信息,没有抛出异常。可以检查下 jsb-engine.js 里的 jsb.onError() 回调有走到吗

测试代码是这样的,目前仍然不会抛出

这里增加的 log 也没有输出

不知道你中间哪里出问题,我这边是会输出错误信息

讨论的一直是原生上的报错哈!mac、iOS 模拟器都是有问题的。浏览器一直是没问题的啊!:joy:

嗯,我这里打印的是 编辑器内模拟器预览 的报错

看这个截图貌似你这是 编辑器内浏览器预览 啊?!使用浏览器的时候开发者模式一直是可以看到报错的,这个不用修改什么哈!
我测试时候用的是 编辑器内模拟器预览,直接看在控制台的log,是没有抛出错误的。

不是的,是编辑器内的 模拟器预览,请在偏好设置里,开启调试界面

  1. 我是基于2.4.0版本根据这两条进行修改,并测试所加代码均已生效,但是现在即便在模拟器的调试工具上也不能正常抛出,不知是不是还要修改其他地方。

  2. 最重要的是,现在构建的原生工程还是不能正常捕获异常,如果项目上线的话,iOS和android将很难追踪问题,因为只要是发生在async修饰,函数内部的错误,以及后续一连串由 async 函数间接调用的函数,都不会把错误抛出,这是影响一连串的,影响范围还是比较广的。

  3. 我试了下如果没有其他方案了,可以在代码编译阶段将 async 修饰的函数体用 try catch 包一下是可以捕获异常的,但是如果代码手动这么加的话,比较麻烦也不美观,是否可以定制编译的模板呢?