1# Analyzing JS Crash
2
3When an application crashes dues to a JS exception, it generates a JS crash log file. You can view the log to locate the error code and analyze the cause of the crash.
4
5This topic describes the JS Crash exception capture scenario, JS Crash fault analysis, and typical cases.
6
7## JS Crash Detection
8
9### JS Crash Log Specifications
10
11The following describes the fields in a process crash log.
12
13```
14Build info:XXX-XXXX X.X.X.XX(XXXXXXXX) <- Build information
15Module name:com.example.myapplication <- Module name
16Version:1.0.0 <- Version number
17Pid:579 <- Process ID
18Uid:0 <- User ID
19Reason:TypeError <- Cause
20Error message:Cannot read property c of undefined <- Error message
21Cannot get SourceMap info, dump raw stack: <- The release package does not contain the **SourceMap** file, and the JavaScript stack fails to parse it.
22SourceCode:
23        var a = b.c;   <- Location of the problematic code
24                ^
25Stacktrace:
26    at onPageShow (entry/src/main/ets/pages/Index.ets:7:13)  <- Call stack of the error code
27           ^                                      ^
28         The error occurs at line 7, column 13 in the entry/src/main/ets/pages/Index.ets file.
29```
30
31You can identify the cause of the crash, mostly application issues, based on Error message and Stacktrace in the logs.
32
33### JS Crash Exception Types
34
35JS crash exceptions are classified into the following types in the **Reason** field based on exception scenarios:
36
37 - **Error**: **Error** is the most basic type. Other error types are inherited from this type. The **Error** object consists of **message** and **name**, which indicate the error message and error name, respectively. Generally, exceptions of the **Error** type are thrown by developers.
38
39 - **TypeError**: As the most common error type at run-time, **TypeError** indicates a variable or parameter that is not of the expected type.
40
41 - **SyntaxError**: **SyntaxError** is also called parsing error. As the most common error type in all programming languages, **SyntaxError** indicates that the syntax does not comply with the syntax specifications of the programming language.
42
43 - **RangeError**: **RangeError** is thrown when a value exceeds the valid range. Common range errors include the following:
44    - The array length is negative or too long.
45    - The numeric parameter exceeds the predefined range.
46    - The number of function stack calls exceeds the maximum.
47
48 - **ReferenceError**: **ReferenceError** is thrown when a variable that does not exist is referenced. Each time a variable is created, the variable name and its value are stored in the key-value format. When a variable is referenced, the value will be located based on the key and returned. If the variable referenced cannot be to be found, **ReferenceError** is thrown.
49
50 - **URI Error**: **URI Error** is thrown when an invalid URI is found in **encodeURI()**, **decodeURI()**, **encodeURIComponent()**, **decodeURIComponent()**, **escape()**, or **unescape()**.
51
52## JS Crash Fault Analysis
53
54### Obtaining the Log
55
56The process crash log is a type of fault log managed together with the app freeze and JS application crash logs by the FaultLogger module. You can obtain process crash logs using any of the following methods:
57
58- Method 1: DevEco Studio
59
60    DevEco Studio collects process crash logs in **/data/log/faultlog/faultlogger/** and archives the logs in FaultLog. For details, see <!--RP1-->[Fault Log](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-fault-log-V5)<!--RP1End-->.
61
62- Method 2: hiAppEvent APIs
63
64    hiAppEvent provides APIs to subscribe to various fault logs. For details, see [Introduction to HiAppEvent](hiappevent-intro.md).
65
66<!--Del-->
67- Method 3: Shell
68
69    When a process crashes, you can find fault logs in **/data/log/faultlog/faultlogger/** on the device. The log files are named in the format of **jscrash-process name-process UID-time (seconds)**. They contain information such as the device name, system version, and process crash call stack.
70
71    ![](figures/jscrash.png)
72<!--DelEnd-->
73
74### Analyzing Faults
75
76Generally, the cause of the fault can be found by locating the problematic code based on the exception scenario, error message, and call stack. The call stack is analyzed in the following cases:
77
78#### 1. StackTrace Scenarios
79
80In JS Crash fault logs, the **StackTrace** field provides the call stack information about the JS Crash exception. Common **StackTrace** information includes the following:
81
821. The stack top indicates the problematic code, as shown in the following example. You can click the link to locate the problematic code.
83    ```
84    Device info:xxx
85    Build info:xxx-xxx x.x.x.xxx(xxxx)
86    Fingerprint:ed1811f3f5ae13c7262b51aab73ddd01df95b2c64466a204e0d70e6461cf1697
87    Module name:com.xxx.xxx
88    Version:1.0.0
89    VersionCode:1000000
90    PreInstalled:No
91    Foreground:Yes
92    Pid:31255
93    Uid:20020145
94    Reason:Error
95    Error name:Error
96    Error message:JSERROR
97    Sourcecode:
98                    throw new ErrOr("JSERROR");
99                          ^
100    Stacktrace:
101        at anonymous (entry/src/main/ets/pages/Index.ets:13:19)
102    ```
103
1042. If "Stack Cannot get SourceMap info, dump raw stack" is displayed in the call stack, as shown in the following example, the system fails to retrieve information from SourceMap and only displays the row number of the problematic code in the compiled code in an eTS stack. You can click the link to identify where the error occurred in the compiled code.
105    ```
106    Device info:xxx
107    Build info:xxx-xxx x.x.x.xxx(xxxx)
108    Fingerprint:a370fceb59011d96e41e97bda139b1851c911012ab8c386d1a2d63986d6d226d
109    Module name:com.xxx.xxx
110    Version:1.0.0
111    Versioncode:1000000
112    PreInstalled:No
113    Foreground:Yes
114    Pid:39185
115    Uid:20020145
116    Reason:Error
117    Error name:Error
118    Error message:JSERROR
119    Stacktrace:
120    Cannot get SourceMap info, dump raw stack:
121        at anonymous (entry/src/main/ets/paqes/Index.ts:49:49)
122    ```
123
1243. If "SourceMap is not initialized yet" is displayed in the call stack, as shown in the following example, SourceMap has not been initialized and the row number of the problematic code in the compiled code in an eTS stack is displayed. In this case, this log is added to notify developers. You can click the link to identify where the error occurred in the compiled code.
125    ```
126    Device info:xxx
127    Build info:xxx-xxx x.x.x.xxx(xxxx)
128    Fingerprint:377ef8529301363f373ce837d0bf83aacfc46112502143237e2f4026e86a0510
129    Module name:com.xxx.xxx
130    Version:1.0.0
131    Versioncode:1000000
132    PreInstalled:No
133    Foreground:Yes
134    Pid:6042
135    Uid:20020145
136    Reason:Error
137    Error name:Error
138    Error message:JSERROR
139    Sourcecode:
140                throw new Error("JSERROR");
141                      ^
142    Stacktrace:
143    SourceMap is not initialized yet
144    at anonymous (entry/src/main/ets/pages/Index.ts:49:49)
145    ```
146
1474. The native stack is printed in the call stack, as shown in the following example. Generally, the **libark_jsruntime.so** dynamic library is at the top of the stack. This is because JS exceptions are thrown by the VM. Search for the error from the top down. Generally, the next frame of **libace_napi.z.so** is the location where an exception is thrown.
148    ```
149    Device info:xxx
150    Build info:xxx-xxx x.x.x.xxx(xxxx)
151    Fingerprint:89f2b64b24d642b0fc64e3a7cf68ca39fecaa580ff5736bb9d6706ea4cdf2c93
152    Module name:com.xxx.xxx
153    Version:1.0.0
154    VersionCode:1000000
155    PreInstalled:No
156    Foreground:No
157    Pid:14325
158    Uid:20020145
159    Reason:ReferenceError
160    Error name:ReferenceError
161    Error message:Cannot find module 'com.xxx.xxx/entry/EntryAbility' , which is application Entry Point
162    Stacktrace:
163    SourceMap is not initialized yet
164    #01 pc 000000000028ba3b /system/libó4/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90)
165    #02 pc 00000000001452ff /system/libó4/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90)
166    #03 pC 0000000000144c9f /system/libó4/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90)
167    #04 pc 00000000001c617b /system/libó4/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90)
168    #05 pc 00000000004c3cb7 /system/libó4/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90)
169    #06 pc 00000000004c045f /system/libó4/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90)
170    #07 pc 000000000038034f /system/libó4/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90)
171    #08 pc 00000000004b2d9b /system/libó4/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90)
172    #09 pc 0000000000037e7f /system/libó4/platformsdk/libace_napi.z.so(10ceafd39b5354314d2fe3059b8f9e4f)
173    #10 pc 00000000000484cf /system/lib64/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014) <- Location where an exception is thrown
174    #11 pc 000000000004fce7 /system/libó4/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014)
175    #12 pc 000000000004e9fb /system/libó4/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014)
176    #13 pc 000000000004eb7b /system/libó4/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014)
177    #14 pc 000000000004f5c7 /system/libó4/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014)
178    #15 pc 00000000000303cf /system/lib64/platformsdk/libuiabilitykit_native.z.so(3203F4CCe84a43b519d0a731dfOdb1a3)
179    ```
180
181#### 2. Call Stack Analysis
182
183Perform call stack analysis as follows:
184
185- Case 1: A hyperlink is provided to go to the problematic code.
186
187  If the path or offset address in the stack trace information in the FaultLog points to a line of code of the current project, a hyperlink is provided. You can click the link in DevEco Studio to locate the code line.
188
189- Case 2: The hyperlink provided to go to the problematic code does not work.
190
191  If "Cannot get Source Map info, dump raw stack" is displayed, the JS stack fails to obtain the row and column numbers for the problematic code. In this case, clicking the provided hyperlink in DevEco Studio navigates you to an incorrect position or displays an error that indicates the position does not exist.
192
193  When an error occurs during the running of application code, the error stack information is printed. If the TS stack fails to obtain the row and column numbers for ArkTS code, the filename extension of the error stack is still "ets". You need to compile the intermediate product in the **build** directory to generate TS code and locate the problematic code in JS. For details, see [Stack Trace Analysis](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-release-app-stack-analysis-V5).
194
195
196## Case Study
197
198The following describes the most common error types, namely, **TypeError** and **Error**, that cause JS crashes.
199
200### TypeError Analysis
201
202As one of the most common errors that cause JS crashes, TypeError is thrown when the variable type is not the expected one. In other words, the variable is not verified before use. The error message is as follows:
203
204```
205Error name:TypeError
206Error message:Cannot read property xxx of undefined
207```
208
209#### Case 1: JS crash occasionally occurs when a gesture value is updated.
210
2111. Obtain the JS crash log:
212
213    ```
214    Generated by HiviewDFX@OpenHarmony
215    ================================================================
216    Device info:xxxx
217    Build info:xxxx
218    Fingerprint:9851196f9fed7fd818170303296ae7a5767c9ab11f38fd8b0072f0e32c42ea39
219    Module name:com.xxx.xxx
220    Version:1.0.0.29
221    VersionCode:10000029
222    PreInstalled:Yes
223    Foreground:No
224    Pid:2780
225    Uid:20020018
226    Reason:TypeError
227    Error name:TypeError
228    Error message:Cannot read property needRenderTranslate of undefined
229    Stacktrace:
230    Cannot get SourceMap info, dump raw stack:
231        at updateGestureValue (phone/src/main/ets/SceneBoard/recent/scenepanel/recentpanel/RecentGesture.ts:51:51)
232        at onRecentGestureActionBegin (phone/src/main/ets/SceneBoard/scenemanager/SCBScenePanel.ts:5609:5609)
233        at anonymous (phone/src/main/ets/SceneBoard/scenemanager/SCBScenePanel.ts:555:555)
234        at anonymous (phone/src/main/ets/SceneBoard/recent/RecentEventView.ts:183:183)
235    ```
236
2372. Analyze log information.
238
239    According to the log information, **TypeError** is reported because the **needRenderTranslate** object is **undefined**. Then, obtain the error location based on the stack trace.
240If "Cannot get SourceMap info, dump raw stack" is displayed, the application is installed using a release package and the eTS row and column numbers cannot be converted from the JS stack. You can refer to [Stack Trace Analysis](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-release-app-stack-analysis-V5) to parse the row number.
241
2423. Locate the error code.
243
244    Based on the preceding JS stack and error variable analysis, the error code can be located as follows:
245
246    ```
247      // Update the gesture value.
248      public updateGestureValue(screenWidth: number, recentScale: number, sceneContainerSessionList: SCBSceneContainerSession[]) {
249        // Calculate the moving distance of the hand.
250        this.translationUpY = (this.multiCardsNum >= 1)? sceneContainerSessionList[this.multiCardsNum - 1].needRenderTranslate.translateY: 0; ---> Number of the error line
251        this.translationDownY = (this.multiCardsNum >= 2) ? sceneContainerSessionList[this.multiCardsNum - 2].needRenderTranslate.translateY : 0;
252        this.screenWidth = px2vp(screenWidth);
253        this.recentScale = recentScale;
254      }
255    ```
256
2574. Solution
258
259    According to the preceding analysis, the member variable **needRenderTranslate** of **sceneContainerSessionList** may be undefined. A protection needs to be added to avoid this type of problem. For example, you can add a '?' operator before the access object for protection.
260
261    ```
262    // Update the gesture value.
263    public updateGestureValue(screenWidth: number, recentScale: number, sceneContainerSessionList: SCBSceneContainerSession[]) {
264      // Calculate the moving distance of the hand.
265      this.translationUpY = (this.multiCardsNum >= 1) ?
266        sceneContainerSessionList[this.multiCardsNum - 1]?.needRenderTranslate.translateY : 0;
267      this.translationDownY = (this.multiCardsNum >= 2) ?
268        sceneContainerSessionList[this.multiCardsNum - 2]?.needRenderTranslate.translateY : 0;
269      this.screenWidth = px2vp(screenWidth);
270      this.recentScale = recentScale;
271    }
272    ```
273
2745. Suggestions
275
276    To solve this problem, we need to add necessary null checks in the coding phase to ensure security of object access. In many scenarios, the null check may only be a workaround. You need to check the object construction or value assignment logic based on service requirements.
277
278### Error Analysis
279
280Error problems are JS exceptions thrown by developers or JS libraries.
281
282There are two scenarios for this type of problem:
2831.	If the application encounters a fault that cannot be rectified, a JS exception is thrown to terminate the service and generate a fault log.
2842.	The service is terminated by an exception thrown by an API of the dependent JS library or module. In this case, you need to consider using try-catch to capture such exceptions.
285
286
287#### Case 1: Throw a custom JS exception to terminate an application.
288
289You can use the following code to throw a JS exception:
290
291```
292throw new Error("TEST JS ERROR")
293```
294
295Based on the fault logs collected by DevEco Studio FaultLog, you can locate the exception based on the JS exception stack.
296
297![](figures/jscrash_error_trigger.png)
298
299To solve this problem, locate the problematic code line based on the fault log and review the context.
300
301#### Case 2: Handle the JS crash caused by a JS exception thrown by a third-party API.
302
3031. Obtain the JS crash log. The key log information is as follows:
304    ```
305    Error name:Error
306    Error message:BussinessError 2501000: Operation failed.
307    Error code:2501000
308    Stacktrace:
309    Cannot get SourceMap info, dump raw stack:
310      at onStart (product/phone/build/default/cache/default/default@CompileArkTS/esmodule/release/feature/systemstatus/linkspeedcomponent/src/main/ets/default/controller/NetSpeedController.ts:50:1)
311      at NetSpeedController (product/phone/build/default/cache/default/default@CompileArkTS/esmodule/release/feature/systemstatus/linkspeedcomponent/src/main/ets/default/controller/NetSpeedController.ts:43:43)
312      at getInstance (product/phone/build/default/cache/default/default@CompileArkTS/esmodule/release/staticcommon/basiccommon/src/main/ets/component/utils/SingletonHelper.ts:17:17)
313      at func_main_0 (product/phone/build/default/cache/default/default@CompileArkTS/esmodule/release/feature/systemstatus/linkspeedcomponent/src/main/ets/default/controller/NetSpeedController.ts:325:325)
314    ```
315
3162. Analyze log information.
317
318    According to the log information, an **Error** exception is thrown by the code. Then, obtain the error location based on the stack trace.
319If "Cannot get SourceMap info, dump raw stack" is displayed, the application is installed using a release package and the eTS row and column numbers cannot be converted from the JS stack. You can refer to [Stack Trace Analysis](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-release-app-stack-analysis-V5) to parse the row number.
320
3213. Locate the error code.
322
323    Based on the preceding JS stack, you can locate the code in the **NetSpeedController.ts** file. The exception is thrown when **wifiManager.on()** is called.
324
325    ```
326    onStart(): void {
327      super.onStart();
328      log.showInfo('onStart');
329      ...
330      wifiManager.on('wifiConnectionChange', (data) => {
331        this.isConnected = data === 1 ? true : false;
332        this.handleUpdateState();
333      });
334      wifiManager.on('wifiStateChange', (data) => {
335        this.isWifiActive = data === 1 ? true : false;
336        this.handleUpdateState();
337      });
338      ...
339    }
340    ```
341
3424. Solution
343
344    According to the analysis of the source code, **wifiManager.on()** throws "BussinessError 2501000: Operation failed" occasionally. If this exception does not cause the application to crash, use try-catch to capture and process the exception. Modify the code as follows:
345
346    ```
347    onStart(): void {
348      super.onStart();
349      log.showInfo('onStart');
350      ...
351      try {
352        wifiManager.on('wifiConnectionChange', (data) => {
353          this.isConnected = data === 1 ? true : false;
354          this.handleUpdateState();
355        });
356      } catch (error) {
357        log.showError('wifiConnectionChange error');
358      }
359      try {
360        wifiManager.on('wifiStateChange', (data) => {
361          this.isWifiActive = data === 1 ? true : false;
362          this.handleUpdateState();
363        });
364      } catch (error) {
365        log.showError('wifiStateChange error');
366      }
367      ...
368    }
369    ```
370
3715. Suggestions
372
373    For such problems, we can use the JS exception mechanism in the coding phase to identify various exception scenarios. In addition, consider capturing the exceptions thrown by APIs to prevent unnecessary interrupts of the main services of the application.
374