1# Subscribing to Crash Events (ArkTS) 2<!--Kit: Performance Analysis Kit--> 3<!--Subsystem: HiviewDFX--> 4<!--Owner: @chenshi51--> 5<!--Designer: @Maplestory--> 6<!--Tester: @yufeifei--> 7<!--Adviser: @foryourself--> 8 9## Overview 10 11The following describes how to subscribe to application crash events by using the ArkTS APIs provided by HiAppEvent. For details about how to use the APIs (such as parameter restrictions and value ranges), see [@ohos.hiviewdfx.hiAppEvent (Application Event Logging)](../reference/apis-performance-analysis-kit/js-apis-hiviewdfx-hiappevent.md). 12 13> **NOTE** 14> 15> The ArkTS APIs can be used to subscribe to the **JsError** and **NativeCrash** events. 16 17## Available APIs 18 19| API| Description| 20| -------- | -------- | 21| addWatcher(watcher: Watcher): AppEventPackageHolder | Adds a watcher to listen for application events.| 22| removeWatcher(watcher: Watcher): void | Removes a watcher to unsubscribe from application events.| 23 24## How to Develop 25 26### Adding an Event Watcher 27 28To subscribe to the crash event successfully, you are advised to add an event watcher after the application starts and before the service logic is executed. 29 30The following describes how to subscribe to the crash event triggered by a button click. 31 321. Create a native C++ project in DevEco Studio. In the **entry/src/main/ets/entryability/EntryAbility.ets** file, import the dependent modules. The sample code is as follows: 33 34 ```ts 35 import { BusinessError } from '@kit.BasicServicesKit'; 36 import { hiAppEvent, hilog } from '@kit.PerformanceAnalysisKit'; 37 import testNapi from 'libentry.so'; 38 ``` 39 402. In the **entry/src/main/ets/entryability/EntryAbility.ets** file, set the [custom parameters of the crash event](hiappevent-watcher-crash-events.md#customizing-crash-event-parameters) and [custom parameters of the crash log specifications](hiappevent-watcher-crash-events.md#customizing-crash-log-specifications) in **onCreate()**. 41 42 ```ts 43 // Build custom parameters for the crash event. 44 let params: Record<string, hiAppEvent.ParamType> = { 45 "test_data": 100, 46 }; 47 // Set custom parameters for the crash event. 48 hiAppEvent.setEventParam(params, hiAppEvent.domain.OS, hiAppEvent.event.APP_CRASH).then(() => { 49 hilog.info(0x0000, 'testTag', `HiAppEvent success to set event param`); 50 }).catch((err: BusinessError) => { 51 hilog.error(0x0000, 'testTag', `HiAppEvent code: ${err.code}, message: ${err.message}`); 52 }); 53 54 // Build custom parameters for crash log specifications. 55 let configParams: Record<string, hiAppEvent.ParamType> = { 56 "extend_pc_lr_printing": true, // Enable the functionality of printing the memory values near the PC and LR. 57 "log_file_cutoff_sz_bytes": 102400, // Truncate the crash log to 100 KB. 58 "simplify_vma_printing": true // Enable simplified printing of maps. 59 }; 60 61 // Set the crash log configuration parameters. 62 hiAppEvent.setEventConfig(hiAppEvent.event.APP_CRASH, configParams).then(() => { 63 hilog.info(0x0000, 'testTag', `HiAppEvent success to set event config.`); 64 }).catch((err: BusinessError) => { 65 hilog.error(0x0000, 'testTag', `HiAppEvent code: ${err.code}, message: ${err.message}`); 66 }); 67 ``` 68 693. In the **entry/src/main/ets/entryability/EntryAbility.ets** file of the project, add the system event subscription to **onCreate()**. The sample code is as follows: 70 71 ```ts 72 let watcher: hiAppEvent.Watcher = { 73 // Set the watcher name. The system identifies different watchers based on their names. 74 name: "watcher", 75 // Add the system events to watch, for example, crash events. 76 appEventFilters: [ 77 { 78 domain: hiAppEvent.domain.OS, 79 names: [hiAppEvent.event.APP_CRASH] 80 } 81 ], 82 // Implement a callback for the registered system event so that you can apply custom processing to the event data obtained. 83 onReceive: (domain: string, appEventGroups: Array<hiAppEvent.AppEventGroup>) => { 84 hilog.info(0x0000, 'testTag', `HiAppEvent onReceive: domain=${domain}`); 85 for (const eventGroup of appEventGroups) { 86 // The event name uniquely identifies a system event. 87 hilog.info(0x0000, 'testTag', `HiAppEvent eventName=${eventGroup.name}`); 88 for (const eventInfo of eventGroup.appEventInfos) { 89 // Apply custom processing to the event data obtained, for example, print the event data in the log. 90 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.domain=${eventInfo.domain}`); 91 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.name=${eventInfo.name}`); 92 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.eventType=${eventInfo.eventType}`); 93 // Obtain the timestamp of the crash event. 94 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.time=${eventInfo.params['time']}`); 95 // Obtain the type of the crash event. 96 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.crash_type=${eventInfo.params['crash_type']}`); 97 // Obtain the foreground and background status of the crashed application. 98 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.foreground=${eventInfo.params['foreground']}`); 99 // Obtain the version information of the crashed application. 100 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.bundle_version=${eventInfo.params['bundle_version']}`); 101 // Obtain the bundle name of the crashed application. 102 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.bundle_name=${eventInfo.params['bundle_name']}`); 103 // Obtain the process ID of the crashed application. 104 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.pid=${eventInfo.params['pid']}`); 105 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.uid=${eventInfo.params['uid']}`); 106 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.uuid=${eventInfo.params['uuid']}`); 107 // Obtain the exception type, cause, and call stack of the crash event. 108 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.exception=${JSON.stringify(eventInfo.params['exception'])}`); 109 // Obtain the log information about the crash event. 110 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.hilog.size=${eventInfo.params['hilog'].length}`); 111 // Obtain the crash log file about the crash event. 112 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.external_log=${JSON.stringify(eventInfo.params['external_log'])}`); 113 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.log_over_limit=${eventInfo.params['log_over_limit']}`); 114 // Obtain the custom test_data of the crash event. 115 hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.test_data=${eventInfo.params['test_data']}`); 116 } 117 } 118 } 119 }; 120 hiAppEvent.addWatcher(watcher); 121 ``` 122 1234. Construct a crash scenario. 124 125 - Construct a **NativeCrash** 126 127 In the **entry/src/main/cpp/napi_init.cpp** file, add the following code to the **Add** method: 128 129 ```cpp 130 int *p = nullptr; 131 int a = *p; // Null pointer dereference. The program crashes. 132 ``` 133 134 In the **entry/src/main/ets/pages/index.ets** file, add the **appCrash** button and construct a scenario for triggering a crash event in **onClick()**. The sample code is as follows: 135 136 ```ts 137 Button("NativeCrash").onClick(()=>{ 138 // In the onClick() function, call the Add method of napi_init.cpp to trigger the NativeCrash event. 139 testNapi.add(2, 3); 140 }) 141 ``` 142 143 - Construct a **JsError** 144 145 In the **entry/src/main/ets/pages/index.ets** file, add the **appCrash** button and construct a scenario for triggering a crash event in **onClick()**. The sample code is as follows: 146 147 ```ts 148 Button("JsError").onClick(()=>{ 149 // Construct a JsError in the button click function to trigger an application crash event. 150 let result: object = JSON.parse(""); 151 }) 152 ``` 153 1545. In DevEco Studio, click the **Run** button to run the project. Tap the **NativeCrash** or **JsError** button on the application screen to trigger a crash event. The system generates logs based on the crash type and triggers the callback. 155 156> **NOTE** 157> 158> **JsError** collects fault information in process and triggers the callback almost instantly. **NativeCrash** collects it out of process, taking roughly 2s on average; the exact time depends on the number of service threads and IPC overhead. The collected fault information is reported asynchronously, which does not block the current service. 159 160### Checking Whether a Watcher Subscribes to Crash Events 161 162Depending on whether an application proactively captures crash events, callbacks are triggered for the crash events at different times. You need to check whether crash events are subscribed to at different times. 163 164**Application not proactively captures crash events** 165 166If the application does not proactively capture the crash exception, the application will exit after the system handles the crash. When the application restarts, HiAppEvent reports the crash event to the registered watcher to complete the callback. 167 168**Application proactively captures crash events** 169 170If an application proactively captures the crash event, a callback is triggered before the application exits. The following are examples: 171 1721. The application does not exit during exception handling. 173 174 When [errorManager.on](../reference/apis-ability-kit/js-apis-app-ability-errorManager.md#errormanageronerror) is used to capture the **JsError** event, a callback is triggered before the application exits. If the application registers the [crash signal](cppcrash-guidelines.md#crash-signals) processing function but does not exit, the **NativeCrash** event triggers a callback before the application exits. 175 1762. If the exception handling takes a long time, the application exits with a delay. 177 178In the development and debugging phase, after HiAppEvent reports a crash event and completes the callback, you can view the **JsError** event information in the **HiLog** window of DevEco Studio. The content of the **NativeCrash** event is different. For details, see [Event Fields](hiappevent-watcher-crash-events.md#fields). The following is an example of a **JsError** event: 179 180```text 181HiAppEvent onReceive: domain=OS 182HiAppEvent eventName=APP_CRASH 183HiAppEvent eventInfo.domain=OS 184HiAppEvent eventInfo.name=APP_CRASH 185HiAppEvent eventInfo.eventType=1 186HiAppEvent eventInfo.params.time=1711440614001 187HiAppEvent eventInfo.params.crash_type=JsError 188HiAppEvent eventInfo.params.foreground=true 189HiAppEvent eventInfo.params.bundle_version=1.0.0 190HiAppEvent eventInfo.params.bundle_name=com.example.myapplication 191HiAppEvent eventInfo.params.pid=2043 192HiAppEvent eventInfo.params.uid=20010043 193HiAppEvent eventInfo.params.uuid=b1e953ba0022c112e4502e28e8b3ad6d95cf3c87bae74068038f03b38ce7f66a 194HiAppEvent eventInfo.params.exception={"message":"Unexpected Text in JSON","name":"SyntaxError","stack":"at anonymous (entry/src/main/ets/pages/Index.ets:55:34)"} 195HiAppEvent eventInfo.params.hilog.size=90 196HiAppEvent eventInfo.params.external_log=["/data/storage/el2/log/hiappevent/APP_CRASH_1711440614112_2043.log"] 197HiAppEvent eventInfo.params.log_over_limit=false 198HiAppEvent eventInfo.params.test_data=100 199``` 200 201### Removing an Event Watcher 202 203```ts 204// Remove the event watcher to unsubscribe from events. 205hiAppEvent.removeWatcher(watcher); 206``` 207<!--RP1--> 208<!--RP1End--> 209