如何使用DFX的ErrorManager来捕获js异常?

问题场景:

使用DFX的ErrorManager来注册错误观测器并捕获js异常,并且希望应用崩溃时进程不会退出。

阅读 586
1 个回答

解决方案 :

应用错误管理接口由errorManager模块提供

错误管理接口功能介绍:

<p id="p86646172238">接口名称</p> <p id="p1766431720230">说明</p>
<p id="p16664121702312">on(type: "error", observer: ErrorObserver): number</p> <p id="p1666471716231">注册错误监听接口,当系统监测到应用异常时会回调该监听。该接口为同步接口,返回值为注册的监听对象对应的序号。</p>
<p id="p16665117142318">off(type: "error", observerId: number, callback: AsyncCallback<void>): void</p> <p id="p1866571713233">以callback的形式解除注册监听,传入的number为之前注册监听时返回的序号。</p>
<p id="p10665717102314">off(type: "error", observerId: number): Promise<void></p> <p id="p1666513176230">以Promise的形式解除注册监听,传入的number为之前注册监听时返回的序号。</p>

当采用callback作为异步回调时,可以在callback中进行下一步处理。当采用Promise对象返回时,可以在Promise对象中类似地处理接口返回值。

异常监听(ErrorObserver)接口功能介绍:

<p id="p13665161711231">接口名称</p> <p id="p36651117132313">说明</p>
<p id="p4665121716233">onUnhandledException(errMsg: string): void</p> <p id="p066514176232">系统回调接口,应用注册后,当应用产生未捕获的异常时的回调。</p>
<p id="p3665101742316">onException?(errObject: Error): void</p> <p id="p366519173230">系统回调接口,应用注册后,当应用产生异常上报js层时的回调。</p>

错误测试:

@Entry
@Component
struct CrashPage {
  @State message: string = 'Hello World'
  build() {
    Row() {
      Column() {
        Button('捕获异常')
          .onClick(() => {
            let tempList = ['0', '1']
            tempList[5].toString()
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

错误观察器注册:

import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import errorManager from '@ohos.app.ability.errorManager';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
 
let registerId = -1;
let callback: errorManager.ErrorObserver = {
    onUnhandledException: (errMsg) => {
        console.log(errMsg);
    },
    onException: (errorObj) => {
        console.log('onException, name: ', errorObj.name);
        console.log('onException, message: ', errorObj.message);
        if (typeof(errorObj.stack) === 'string') {
            console.log('onException, stack: ', errorObj.stack);
        }
    }
}
let abilityWant: Want;
 
export default class EntryAbility extends UIAbility {
    onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
        console.log("[Demo] EntryAbility onCreate");
        registerId = errorManager.on("error", callback);
        abilityWant = want;
    }
 
    onDestroy() {
        console.log("[Demo] EntryAbility onDestroy");
        errorManager.off("error", registerId, (result) => {
            console.log("[Demo] result " + result.code + ";" + result.message);
        });
    }
 
    onWindowStageCreate(windowStage: window.WindowStage) {
        // Main window is created, set main page for this ability
        console.log("[Demo] EntryAbility onWindowStageCreate");
 
        windowStage.loadContent("pages/index", (err, data) => {
            if (err.code) {
                console.error('Failed to load the content. Cause:' + JSON.stringify(err));
                return;
            }
            console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data));
        });
    }
 
    onWindowStageDestroy() {
        // Main window is destroyed, release UI related resources
        console.log("[Demo] EntryAbility onWindowStageDestroy");
    }
 
    onForeground() {
        // Ability has brought to foreground
        console.log("[Demo] EntryAbility onForeground");
    }
 
    onBackground() {
        // Ability has back to background
        console.log("[Demo] EntryAbility onBackground");
    }
};

实现效果:

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进