creator-错误捕获

creator-错误捕获


前篇

遇到 exception 和未知的错误时, 需要捕获, 方便上线后排除问题.


web 平台

  • 提供了监听函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    window.onunhandledrejection = (event: PromiseRejectionEvent) => {
    console.error('--- onunhandledrejection message:', event.reason.message)
    console.error('--- onunhandledrejection stack:', event.reason.stack)
    }
    window.onerror = function (errMsg: string, file: string, lineNo: number, columnNo: number, errObj: Error, ...args) {
    console.error('--- onunhandledrejection errMsg:', errMsg)
    console.error('--- onunhandledrejection file:', file)
    console.error('--- onunhandledrejection lineNo:', lineNo)
    console.error('--- onunhandledrejection columnNo:', columnNo)
    console.error('--- onunhandledrejection errObj:', errObj)

    console.error('--- onunhandledrejection args:', args)
    }

原生平台

cocos 模式是可以通过 window['__errorHandler'] 捕获错误, 但是 promise 的错误捕获不到

  1. 修改 CocosApplication.cpp 文件, 把错误传给 js

    如: d:/CocosEditor/Creator/3.8.3/resources/resources/3d/engine/native/cocos/application/CocosApplication.cpp, 里面就是抛出了一个 CC_LOG_ERROR

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    void CocosApplication::handleException(const char *location, const char *message, const char *stack) {
    // Send exception information to server like Tencent Bugly.

    // 尝试获取 window.gMyErrHandler, 有的话把报错信息传过去, 没有还是默认的 CC_LOG_ERROR
    se::ScriptEngine* engine = se::ScriptEngine::getInstance();
    se::AutoHandleScope hs;
    se::Value globalVal;
    if (engine->getGlobalObject()->getProperty("window", &globalVal)) {
    se::Object* globalObj = globalVal.toObject();
    se::Value funcVal;
    if (globalObj->getProperty("gMyErrHandler", &funcVal) && funcVal.isObject() && funcVal.toObject()->isFunction()) {
    se::Object* funcObj = funcVal.toObject();
    se::ValueArray args;
    args.push_back(se::Value(location));
    args.push_back(se::Value(message));
    args.push_back(se::Value(stack));
    funcObj->call(args, globalObj);
    } else {
    CC_LOG_ERROR("\nUncaught Exception:\n - location : %s\n - msg : %s\n - detail : \n %s\n", location, message, stack);
    }
    } else {
    CC_LOG_ERROR("\nUncaught Exception:\n - location : %s\n - msg : %s\n - detail : \n %s\n", location, message, stack);
    }
    }
  2. js 中注册一个 gMyErrHandler 处理函数

    1
    2
    3
    4
    5
    if (Tool.IsMobile()) {
    window.gMyErrHandler = function (location, msg, stack) {
    ...
    }
    }