[TIMOB-25899] Android: Modify JSON.stringify(Error) to not return "{}"
GitHub Issue | n/a |
---|---|
Type | Improvement |
Priority | Low |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2018-09-19T21:34:55.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 7.5.0 |
Components | Android |
Labels | android, error, json, json.stringify, parity |
Reporter | Aminul Islam |
Assignee | Joshua Quick |
Created | 2018-03-23T19:24:32.000+0000 |
Updated | 2018-10-05T18:52:38.000+0000 |
Description
Hello !
We were trying to log some handled exceptions with the APM module for Android (apm.logHandledException( ) ) and we just noticed whenever we try to instantiate a Javascript Error in Android , this always comes out as an empty object ( { } ), where as, when doing the very same thing in iOS will work with no issues.
This however, has only been tested in simulators/emulators.
It was also tested with Ti SDK 7.x and 6.x. In both cases new Error seems to be broken in Android, but working in iOS.
Sample app: https://propelics.box.com/s/q8nryev5c6fc8eqzl3rem21jjd792vj4
var e = new Error('Some error');
var e2 = new Error();
console.log('e=' + JSON.stringify(e));
console.log('e2=' + JSON.stringify(e2));
Steps to reproduce:
1) Take a look at index.js and see how we're trying to instantiate 2 Error objects, then printing them in the console.
2) Run the application in Android (we've been using emulators with Android 6.0 and 7.1.1)
3) When the application launches look at the console. The printed logs will be empty objects:
[INFO] e={}
[INFO] e2={}
4) Re-run the app in iOS
5) Observe the console output and how actual error objects will be printed:
[INFO] e={"line":55,"column":19,"sourceURL":"file:///Users/user/Library/Developer/CoreSimulator/Devices/63801195-0FE5-4A3F-9615-F1ABAAB35DFC/data/Containers/Bundle/Application/D4F143DB-E591-4258-9567-6D294EBEB265/BlankApp.app/alloy/controllers/index.js"}
[INFO] e2={"line":56,"column":20,"sourceURL":"file:///Users/user/Library/Developer/CoreSimulator/Devices/63801195-0FE5-4A3F-9615-F1ABAAB35DFC/data/Containers/Bundle/Application/D4F143DB-E591-4258-9567-6D294EBEB265/BlankApp.app/alloy/controllers/index.js"}
The
Error
object is probably fine. This is likely an issue withJSON.stringify()
not knowing how to enumerate theError
object's fields.For reference: V8 bug around Error properties not being enumerable https://bugs.chromium.org/p/v8/issues/detail?id=1595 Node bug for this behaviour: https://github.com/nodejs/node-v0.x-archive/issues/1634 (their fix at the time https://github.com/nodejs/node-v0.x-archive/commit/389e2a07e676e5be3b8cbd94f0a0f7ebccb47f47) Interestingly doing {var e = new Error('Some error');{Ti.API.info(e);}} gives
[INFO] Error: Some error
. In console.js we probably want to check if what we're passing to Ti.API.It sounds like this behavior is actually according to the ES5 spec in V8. If you'd like to log an Error, you could always build the string manually. The most important property is
stack
, which holds the message and stacktrace of the error and would likely hold all the info you'd want. They also typically have amessage
property which is just the message passed in (so here it'd be'Some error'
).We also added a
nativeStack
property for any under the hood java stacktrace on Android (if we had one), which will land in 7.2.0. The relevant tickets are: TIMOB-25963 and TIMOB-25965 (though I'm not sure they were updated to note the new property). So, long story short: the properties on Error are not enumerable by default on V8 due to complying more strictly to the ES5 spec, but it's relatively easy to just log thestack
property if it's available, and fall back to themessage
property if not. But we may want to alter our JSON.stringify impl on Android to specifically handle this case.PR (master): https://github.com/appcelerator/titanium_mobile/pull/10112
FR Passed.
JSON.stringify(Error)
returns the appropriate error & not {}. Studio Ver: 5.1.1.201809051655 SDK Ver: 7.5.0 local build OS Ver: 10.13.5 Xcode Ver: Xcode 9.4.1 Appc NPM: 4.2.13 Appc CLI: 7.0.6 Daemon Ver: 1.1.3 Ti CLI Ver: 5.1.1 Alloy Ver: 1.13.2 Node Ver: 8.9.1 NPM Ver: 5.5.1 Java Ver: 10.0.2 Devices: ⇨ google Nexus 5 (Android 6.0.1) ⇨ google Nexus 6P (Android 8.1.0) Emulator: ⇨ Android 4.1.2PR Merged.
Verified the fix on SDK 7.5.0.v20181004095510. Error returns correctly. Closing.