1# Development of Error Manager
2
3## Overview
4
5If coding specification issues or errors exist in the code of an application, the application may encounter unexpected errors, for example, uncaught exceptions or application lifecycle timeouts, while it is running. In such a case, the application may exit unexpectedly. Error logs, however, are usually stored on users' local storage, making it inconvenient to locate faults. With the APIs provided by the **errorManager** module, the related errors and logs will be reported to your service platform for fault locating before application exits.
6
7## Available APIs
8
9Application error management APIs are provided by the [errorManager](../reference/apis-ability-kit/js-apis-app-ability-errorManager.md#) module. For details about how to import the module, see [Development Example](#development-example).
10
11**Application Error Management APIs**
12
13| API                                                      | Description                                                |
14| ------------------------------------------------------------ | ---------------------------------------------------- |
15| on(type: "error", observer: ErrorObserver): number       | Registers an observer for application errors. A callback will be invoked when an application error is detected. This API works in a synchronous manner. The return value is the serial number(SN) of the registered observer.|
16| off(type: "error", observerId: number,  callback: AsyncCallback\<void\>): void | Unregisters an observer in callback mode. The number is the SN of the registered observer. |
17| off(type: "error", observerId: number): Promise\<void\> | Unregisters an observer in promise mode. The number is the SN of the registered observer. |
18| on(type: 'loopObserver', timeout: number, observer: LoopObserver): void<sup>12+</sup> | Registers an observer for the message processing duration of the main thread. A callback will be invoked if a main thread jank event occurs. This API can be called only in the main thread. A new observer will overwrite the previous one. |
19| off(type: 'loopObserver', observer?: LoopObserver): void<sup>12+</sup> | Unregisters the observer for message processing timeouts of the main thread. |
20
21When an asynchronous callback is used, the return value can be processed directly in the callback. If a promise is used, the return value can also be processed in the promise in a similar way. For details about the result codes, see [Result Codes for Unregistering an Observer](#result-codes-for-unregistering-an-observer).
22
23
24**ErrorObserver APIs**
25
26| API                        | Description                                                        |
27| ------------------------------ | ------------------------------------------------------------ |
28| onUnhandledException(errMsg: string): void | Called when an uncaught exception is reported after the application is registered.|
29| onException?(errObject: Error): void | Called when an application exception is reported to the JavaScript layer after the application is registered.|
30
31
32**LoopObserver APIs**
33
34| API                        | Description                                                        |
35| ------------------------------ | ------------------------------------------------------------ |
36| onLoopTimeOut?(timeout: number): void<sup>12+</sup> | Called when the message processing of the main thread times out.|
37
38
39### Result Codes for Unregistering an Observer
40
41| Result Code| Description                       |
42| ------ | ---------------------------  |
43| 0      |  Normal.                         |
44| -1     | Input number not exist.             |
45| -2     | Invalid parameter.      |
46
47## Development Example
48
49> **NOTE**
50> You are advised to add a synchronous exit function at the end of the exception callback. Otherwise, multiple exception callbacks may be invoked.
51
52```ts
53import { AbilityConstant, errorManager, UIAbility, Want } from '@kit.AbilityKit';
54import { window } from '@kit.ArkUI';
55import process from '@ohos.process';
56
57let registerId = -1;
58let callback: errorManager.ErrorObserver = {
59    onUnhandledException: (errMsg) => {
60        console.log(errMsg);
61    },
62    onException: (errorObj) => {
63        console.log('onException, name: ', errorObj.name);
64        console.log('onException, message: ', errorObj.message);
65        if (typeof(errorObj.stack) === 'string') {
66            console.log('onException, stack: ', errorObj.stack);
67        }
68        //After the callback is executed, exit the process synchronously to avoid triggering exceptions for multiple times.
69        let pro = new process.ProcessManager();
70        pro.exit(0);
71    }
72}
73
74let abilityWant: Want;
75
76export default class EntryAbility extends UIAbility {
77    onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
78        console.log("[Demo] EntryAbility onCreate");
79        registerId = errorManager.on("error", callback);
80        abilityWant = want;
81    }
82
83    onDestroy() {
84        console.log("[Demo] EntryAbility onDestroy");
85        errorManager.off("error", registerId, (result) => {
86            console.log("[Demo] result " + result.code + ";" + result.message);
87        });
88    }
89
90    onWindowStageCreate(windowStage: window.WindowStage) {
91        // Main window is created, set main page for this ability
92        console.log("[Demo] EntryAbility onWindowStageCreate");
93
94        windowStage.loadContent("pages/index", (err, data) => {
95            if (err.code) {
96                console.error('Failed to load the content. Cause:' + JSON.stringify(err));
97                return;
98            }
99            console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data));
100        });
101    }
102
103    onWindowStageDestroy() {
104        // Main window is destroyed, release UI related resources
105        console.log("[Demo] EntryAbility onWindowStageDestroy");
106    }
107
108    onForeground() {
109        // Ability has brought to foreground
110        console.log("[Demo] EntryAbility onForeground");
111    }
112
113    onBackground() {
114        // Ability has back to background
115        console.log("[Demo] EntryAbility onBackground");
116    }
117};
118```
119