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``` 14Device info:XXX <- Device information 15Build info:XXX-XXXX X.X.X.XX(XXXXXXXX) <- Build information 16Fingerprint:ed1811f3f5ae13c7262b51aab73ddd01df95b2c64466a204e0d70e6461cf1697 <- Feature information 17Timestamp:XXXX-XX-XX XX:XX:XX.XXX <- Timestamp 18Module name:com.example.myapplication <- Module name 19Version:1.0.0 <- Version number 20VersionCode:1000000 <- Version code 21Pid:579 <- Process ID 22Uid:0 <- User ID 23Reason:TypeError <- Cause 24Error message:Cannot read property c of undefined <- Error message 25Cannot get SourceMap info, dump raw stack: <- The release package does not contain the **SourceMap** file, and the JavaScript stack fails to parse it. 26SourceCode: 27 var a = b.c; <- Location of the problematic code 28 ^ 29Stacktrace: 30 at onPageShow entry (entry/src/main/ets/pages/Index.ets:7:13) <- Call stack of the error code 31 ^ ^ ^ 32 Function name Module bundle name The row and column numbers in the file 33``` 34 35You can identify the cause of the crash, mostly application issues, based on Error message and Stacktrace in the logs. 36 37### JS Crash Exception Types 38 39JS crash exceptions are classified into the following types in the **Reason** field based on exception scenarios: 40 41 - **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. 42 43 - **TypeError**: As the most common error type at run-time, **TypeError** indicates a variable or parameter that is not of the expected type. 44 45 - **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. 46 47 - **RangeError**: **RangeError** is thrown when a value exceeds the valid range. Common range errors include the following: 48 - The array length is negative or too long. 49 - The numeric parameter exceeds the predefined range. 50 - The number of function stack calls exceeds the maximum. 51 52 - **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. 53 54 - **URI Error**: **URI Error** is thrown when an invalid URI is found in **encodeURI()**, **decodeURI()**, **encodeURIComponent()**, **decodeURIComponent()**, **escape()**, or **unescape()**. 55 56## JS Crash Fault Analysis 57 58### Obtaining the Log 59 60The 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: 61 62- Method 1: DevEco Studio 63 64 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-->. 65 66- Method 2: hiAppEvent APIs 67 68 hiAppEvent provides APIs to subscribe to various fault logs. For details, see [Introduction to HiAppEvent](hiappevent-intro.md). 69 70<!--Del--> 71- Method 3: Shell 72 73 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 (milliseconds).log**. They contain information such as the device name, system version, and process crash call stack. 74 75  76<!--DelEnd--> 77 78### Analyzing Faults 79 80Generally, 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: 81 82#### 1. StackTrace Scenarios 83 84In JS Crash fault logs, the **StackTrace** field provides the call stack information about the JS Crash exception. Common **StackTrace** information includes the following: 85 861. The stack top indicates the problematic code, as shown in the following example. You can click the link to locate the problematic code. 87 ``` 88 Device info:xxx 89 Build info:xxx-xxx x.x.x.xxx(xxxx) 90 Fingerprint:ed1811f3f5ae13c7262b51aab73ddd01df95b2c64466a204e0d70e6461cf1697 91 Timestamp:xxxx-xx-xx xx:xx:xx.xxx 92 Module name:com.xxx.xxx 93 Version:1.0.0 94 VersionCode:1000000 95 PreInstalled:No 96 Foreground:Yes 97 Pid:31255 98 Uid:20020145 99 Reason:Error 100 Error name:Error 101 Error message:JSERROR 102 Sourcecode: 103 throw new ErrOr("JSERROR"); 104 ^ 105 Stacktrace: 106 at anonymous entry (entry/src/main/ets/pages/Index.ets:13:19) 107 ``` 108 1092. 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. 110 ``` 111 Device info:xxx 112 Build info:xxx-xxx x.x.x.xxx(xxxx) 113 Fingerprint:a370fceb59011d96e41e97bda139b1851c911012ab8c386d1a2d63986d6d226d 114 Timestamp:xxxx-xx-xx xx:xx:xx.xxx 115 Module name:com.xxx.xxx 116 Version:1.0.0 117 VersionCode:1000000 118 PreInstalled:No 119 Foreground:Yes 120 Pid:39185 121 Uid:20020145 122 Reason:Error 123 Error name:Error 124 Error message:JSERROR 125 Stacktrace: 126 Cannot get SourceMap info, dump raw stack: 127 at anonymous entry (entry/src/main/ets/pages/Index.ts:49:49) 128 ``` 129 1303. 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. The following is an example. 131 ``` 132 Device info:xxx 133 Build info:xxx-xxx x.x.x.xxx(xxxx) 134 Fingerprint:377ef8529301363f373ce837d0bf83aacfc46112502143237e2f4026e86a0510 135 Timestamp:xxxx-xx-xx xx:xx:xx.xxx 136 Module name:com.xxx.xxx 137 Version:1.0.0 138 Versioncode:1000000 139 PreInstalled:No 140 Foreground:Yes 141 Pid:6042 142 Uid:20020145 143 Reason:Error 144 Error name:Error 145 Error message:JSERROR 146 Sourcecode: 147 throw new Error("JSERROR"); 148 ^ 149 Stacktrace: 150 SourceMap is not initialized yet 151 at anonymous entry (entry/src/main/ets/pages/Index.ts:49:49) 152 ``` 153 1544. 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. The following is an example. 155 ``` 156 Device info:xxx 157 Build info:xxx-xxx x.x.x.xxx(xxxx) 158 Fingerprint:89f2b64b24d642b0fc64e3a7cf68ca39fecaa580ff5736bb9d6706ea4cdf2c93 159 Timestamp:xxxx-xx-xx xx:xx:xx.xxx 160 Module name:com.xxx.xxx 161 Version:1.0.0 162 VersionCode:1000000 163 PreInstalled:No 164 Foreground:No 165 Pid:14325 166 Uid:20020145 167 Reason:ReferenceError 168 Error name:ReferenceError 169 Error message:Cannot find module 'com.xxx.xxx/entry/EntryAbility' , which is application Entry Point 170 Stacktrace: 171 SourceMap is not initialized yet 172 #01 pc 000000000028ba3b /system/lib64/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90) 173 #02 pc 00000000001452ff /system/lib64/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90) 174 #03 pC 0000000000144c9f /system/lib64/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90) 175 #04 pc 00000000001c617b /system/lib64/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90) 176 #05 pc 00000000004c3cb7 /system/lib64/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90) 177 #06 pc 00000000004c045f /system/lib64/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90) 178 #07 pc 000000000038034f /system/lib64/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90) 179 #08 pc 00000000004b2d9b /system/lib64/platformsdk/libark_jsruntime.so(bf6ea8e474ac3e417991f101e062fa90) 180 #09 pc 0000000000037e7f /system/lib64/platformsdk/libace_napi.z.so(10ceafd39b5354314d2fe3059b8f9e4f) 181 #10 pc 00000000000484cf /system/lib64/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014) <- Location where an exception is thrown 182 #11 pc 000000000004fce7 /system/lib64/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014) 183 #12 pc 000000000004e9fb /system/lib64/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014) 184 #13 pc 000000000004eb7b /system/lib64/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014) 185 #14 pc 000000000004f5c7 /system/lib64/platformsdk/libruntime.z.so(3f6305a3843fae1de148a06eec4bd014) 186 #15 pc 00000000000303cf /system/lib64/platformsdk/libuiabilitykit_native.z.so(3203F4CCe84a43b519d0a731dfOdb1a3) 187 ``` 188 189#### 2. Call Stack Analysis 190 191Perform call stack analysis as follows: 192 193- Case 1: A hyperlink is provided to go to the problematic code. 194 195 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. 196 197- Case 2: The hyperlink provided to go to the problematic code does not work. 198 199 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. 200 201 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). 202 203 204## Case Study 205 206The following describes the most common error types, namely, **TypeError** and **Error**, that cause JS crashes. 207 208### TypeError Analysis 209 210As 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: 211 212``` 213Error name:TypeError 214Error message:Cannot read property xxx of undefined 215``` 216 217#### Case 1: JS crash occasionally occurs when a gesture value is updated. 218 2191. Obtain the JS crash log: 220 221 ``` 222 Generated by HiviewDFX@OpenHarmony 223 ================================================================ 224 Device info:xxxx 225 Build info:xxxx 226 Fingerprint:9851196f9fed7fd818170303296ae7a5767c9ab11f38fd8b0072f0e32c42ea39 227 Timestamp:xxxx-xx-xx xx:xx:xx.xxx 228 Module name:com.xxx.xxx 229 Version:1.0.0.29 230 VersionCode:10000029 231 PreInstalled:Yes 232 Foreground:No 233 Pid:2780 234 Uid:20020018 235 Reason:TypeError 236 Error name:TypeError 237 Error message:Cannot read property needRenderTranslate of undefined 238 Stacktrace: 239 Cannot get SourceMap info, dump raw stack: 240 at updateGestureValue entry (phone/src/main/ets/SceneBoard/recent/scenepanel/recentpanel/RecentGesture.ts:51:51) 241 at onRecentGestureActionBegin entry (phone/src/main/ets/SceneBoard/scenemanager/SCBScenePanel.ts:5609:5609) 242 at anonymous entry (phone/src/main/ets/SceneBoard/scenemanager/SCBScenePanel.ts:555:555) 243 at anonymous entry (phone/src/main/ets/SceneBoard/recent/RecentEventView.ts:183:183) 244 ``` 245 2462. Analyze log information. 247 248 According to the log information, **TypeError** is reported because the **needRenderTranslate** object is **undefined**. Then, obtain the error location based on the stack trace. 249If "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. 250 2513. Locate the error code. 252 253 Based on the preceding JS stack and error variable analysis, the error code can be located as follows: 254 255 ``` 256 // Update the gesture value. 257 public updateGestureValue(screenWidth: number, recentScale: number, sceneContainerSessionList: SCBSceneContainerSession[]) { 258 // Calculate the moving distance of the hand. 259 this.translationUpY = (this.multiCardsNum >= 1)? sceneContainerSessionList[this.multiCardsNum - 1].needRenderTranslate.translateY: 0; ---> Number of the error line 260 this.translationDownY = (this.multiCardsNum >= 2) ? sceneContainerSessionList[this.multiCardsNum - 2].needRenderTranslate.translateY : 0; 261 this.screenWidth = px2vp(screenWidth); 262 this.recentScale = recentScale; 263 } 264 ``` 265 2664. Solution 267 268 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. 269 270 ``` 271 // Update the gesture value. 272 public updateGestureValue(screenWidth: number, recentScale: number, sceneContainerSessionList: SCBSceneContainerSession[]) { 273 // Calculate the moving distance of the hand. 274 this.translationUpY = (this.multiCardsNum >= 1) ? 275 sceneContainerSessionList[this.multiCardsNum - 1]?.needRenderTranslate.translateY : 0; 276 this.translationDownY = (this.multiCardsNum >= 2) ? 277 sceneContainerSessionList[this.multiCardsNum - 2]?.needRenderTranslate.translateY : 0; 278 this.screenWidth = px2vp(screenWidth); 279 this.recentScale = recentScale; 280 } 281 ``` 282 2835. Suggestions 284 285 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. 286 287### Error Analysis 288 289Error problems are JS exceptions thrown by developers or JS libraries. 290 291There are two scenarios for this type of problem: 2921. If the application encounters a fault that cannot be rectified, a JS exception is thrown to terminate the service and generate a fault log. 2932. 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. 294 295 296#### Case 1: Throw a custom JS exception to terminate an application. 297 298You can use the following code to throw a JS exception: 299 300``` 301throw new Error("TEST JS ERROR") 302``` 303 304Based on the fault logs collected by DevEco Studio FaultLog, you can locate the exception based on the JS exception stack. 305 306 307 308To solve this problem, locate the problematic code line based on the fault log and review the context. 309 310#### Case 2: Handle the JS crash caused by a JS exception thrown by a third-party API. 311 3121. Obtain the JS crash log. The key log information is as follows: 313 ``` 314 Error name:Error 315 Error message:BussinessError 2501000: Operation failed. 316 Error code:2501000 317 Stacktrace: 318 Cannot get SourceMap info, dump raw stack: 319 at onStart entry (product/phone/build/default/cache/default/default@CompileArkTS/esmodule/release/feature/systemstatus/linkspeedcomponent/src/main/ets/default/controller/NetSpeedController.ts:50:1) 320 at NetSpeedController entry (product/phone/build/default/cache/default/default@CompileArkTS/esmodule/release/feature/systemstatus/linkspeedcomponent/src/main/ets/default/controller/NetSpeedController.ts:43:43) 321 at getInstance entry (product/phone/build/default/cache/default/default@CompileArkTS/esmodule/release/staticcommon/basiccommon/src/main/ets/component/utils/SingletonHelper.ts:17:17) 322 at func_main_0 entry (product/phone/build/default/cache/default/default@CompileArkTS/esmodule/release/feature/systemstatus/linkspeedcomponent/src/main/ets/default/controller/NetSpeedController.ts:325:325) 323 ``` 324 3252. Analyze log information. 326 327 According to the log information, an **Error** exception is thrown by the code. Then, obtain the error location based on the stack trace. 328If "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. 329 3303. Locate the error code. 331 332 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. 333 334 ``` 335 onStart(): void { 336 super.onStart(); 337 log.showInfo('onStart'); 338 ... 339 wifiManager.on('wifiConnectionChange', (data) => { 340 this.isConnected = data === 1 ? true : false; 341 this.handleUpdateState(); 342 }); 343 wifiManager.on('wifiStateChange', (data) => { 344 this.isWifiActive = data === 1 ? true : false; 345 this.handleUpdateState(); 346 }); 347 ... 348 } 349 ``` 350 3514. Solution 352 353 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: 354 355 ``` 356 onStart(): void { 357 super.onStart(); 358 log.showInfo('onStart'); 359 ... 360 try { 361 wifiManager.on('wifiConnectionChange', (data) => { 362 this.isConnected = data === 1 ? true : false; 363 this.handleUpdateState(); 364 }); 365 } catch (error) { 366 log.showError('wifiConnectionChange error'); 367 } 368 try { 369 wifiManager.on('wifiStateChange', (data) => { 370 this.isWifiActive = data === 1 ? true : false; 371 this.handleUpdateState(); 372 }); 373 } catch (error) { 374 log.showError('wifiStateChange error'); 375 } 376 ... 377 } 378 ``` 379 3805. Suggestions 381 382 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. 383