{ "id": "171392", "key": "TIMOB-25899", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "20238", "description": "", "name": "Release 7.5.0", "archived": false, "released": true, "releaseDate": "2018-11-15" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2018-09-19T21:34:55.000+0000", "created": "2018-03-23T19:24:32.000+0000", "epic": { "id": 170942, "key": "TIMOB-25710", "name": "SDK Parity effort", "summary": "SDK Parity effort", "color": { "key": "color_1" }, "done": false }, "priority": { "name": "Low", "id": "4" }, "labels": [ "android", "error", "json", "json.stringify", "parity" ], "versions": [], "issuelinks": [ { "id": "56791", "type": { "id": "10002", "name": "Duplicate", "inward": "is duplicated by", "outward": "duplicates" }, "inwardIssue": { "id": "167540", "key": "TIMOB-24673", "fields": { "summary": "Android: Error thrown from require is an empty object", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "None", "id": "6" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2018-10-05T18:52:38.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "Hello !\r\nWe 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.\r\nThis however, has only been tested in simulators/emulators.\r\n\r\nIt 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.\r\n\r\n\r\nSample app: https://propelics.box.com/s/q8nryev5c6fc8eqzl3rem21jjd792vj4\r\n{code}\r\nvar e = new Error('Some error');\r\nvar e2 = new Error();\r\n\r\nconsole.log('e=' + JSON.stringify(e));\r\nconsole.log('e2=' + JSON.stringify(e2));\r\n{code}\r\n\r\nSteps to reproduce:\r\n1) Take a look at index.js and see how we're trying to instantiate 2 Error objects, then printing them in the console.\r\n2) Run the application in Android (we've been using emulators with Android 6.0 and 7.1.1)\r\n3) When the application launches look at the console. The printed logs will be empty objects:\r\n[INFO] e={}\r\n[INFO] e2={}\r\n4) Re-run the app in iOS\r\n5) Observe the console output and how actual error objects will be printed:\r\n[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\"}\r\n[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\"}\r\n", "attachment": [], "flagged": false, "summary": "Android: Modify JSON.stringify(Error) to not return \"{}\"", "creator": { "name": "aislam", "key": "aislam", "displayName": "Aminul Islam", "active": false, "timeZone": "Etc/GMT-6" }, "subtasks": [], "reporter": { "name": "aislam", "key": "aislam", "displayName": "Aminul Islam", "active": false, "timeZone": "Etc/GMT-6" }, "environment": "Version of the APM we're using is 3.1.0 for both Android and iOS\r\nOperating System\r\nName = Mac OS X\r\nVersion = 10.13.3\r\nArchitecture = 64bit\r\n# CPUs = 8\r\nMemory = 16.0GB\r\n\r\nNode.js\r\nNode.js Version = 6.11.5\r\nnpm Version = 3.10.10\r\n\r\nTitanium CLI\r\nCLI Version = 5.0.14\r\nnode-appc Version = 0.2.41\r\n\r\nTitanium SDKs\r\n7.1.0.GA\r\nVersion = 7.1.0", "closedSprints": [ { "id": 1073, "state": "closed", "name": "2018 Sprint 19 SDK", "startDate": "2018-09-09T21:02:56.422Z", "endDate": "2018-09-23T21:02:00.000Z", "completeDate": "2018-09-23T22:28:10.932Z", "originBoardId": 114 }, { "id": 1058, "state": "closed", "name": "2018 Sprint 16 SDK", "startDate": "2018-07-29T22:26:06.486Z", "endDate": "2018-08-12T22:26:00.000Z", "completeDate": "2018-08-13T17:38:16.757Z", "originBoardId": 114 }, { "id": 1028, "state": "closed", "name": "2018 Sprint 09 SDK", "startDate": "2018-04-22T22:53:08.928Z", "endDate": "2018-05-06T22:53:00.000Z", "completeDate": "2018-05-07T00:02:15.883Z", "originBoardId": 114 }, { "id": 1045, "state": "closed", "name": "2018 Sprint 13 SDK", "startDate": "2018-06-17T20:47:13.621Z", "endDate": "2018-07-01T20:47:00.000Z", "completeDate": "2018-07-02T18:40:05.029Z", "originBoardId": 114 }, { "id": 1065, "state": "closed", "name": "2016 Sprint 17 SDK", "startDate": "2018-08-13T17:39:36.846Z", "endDate": "2018-08-27T17:39:00.000Z", "completeDate": "2018-08-29T16:10:57.013Z", "originBoardId": 114 }, { "id": 1034, "state": "closed", "name": "2018 Sprint 10 SDK", "startDate": "2018-05-07T00:03:21.636Z", "endDate": "2018-05-21T00:03:00.000Z", "completeDate": "2018-05-20T20:54:58.928Z", "originBoardId": 114 }, { "id": 1050, "state": "closed", "name": "2018 Sprint 14 SDK", "startDate": "2018-07-01T18:40:57.193Z", "endDate": "2018-07-15T18:40:00.000Z", "completeDate": "2018-07-16T03:27:08.720Z", "originBoardId": 114 }, { "id": 1035, "state": "closed", "name": "2018 Sprint 11 SDK", "startDate": "2018-05-20T20:57:43.542Z", "endDate": "2018-06-03T20:57:00.000Z", "completeDate": "2018-06-04T15:13:14.425Z", "originBoardId": 114 }, { "id": 1053, "state": "closed", "name": "2018 Sprint 15 SDK", "startDate": "2018-07-15T21:52:05.453Z", "endDate": "2018-07-29T21:52:00.000Z", "completeDate": "2018-07-29T22:25:11.723Z", "originBoardId": 114 }, { "id": 1070, "state": "closed", "name": "2018 Sprint 18 SDK", "startDate": "2018-08-26T16:14:35.297Z", "endDate": "2018-09-09T16:14:00.000Z", "completeDate": "2018-09-11T20:59:21.495Z", "originBoardId": 114 }, { "id": 1039, "state": "closed", "name": "2018 Sprint 12 SDK", "startDate": "2018-06-03T15:22:23.401Z", "endDate": "2018-06-17T15:22:00.000Z", "completeDate": "2018-06-18T20:45:36.363Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "435872", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "The {{Error}} object is probably fine. This is likely an issue with {{JSON.stringify()}} not knowing how to enumerate the {{Error}} object's fields.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-23T19:50:49.000+0000", "updated": "2018-03-23T19:50:49.000+0000" }, { "id": "435873", "author": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "body": "For reference: \r\nV8 bug around Error properties not being enumerable https://bugs.chromium.org/p/v8/issues/detail?id=1595 \r\nNode 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)\r\n\r\nInterestingly 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. is an error and format it. I'm not sure what we can do on the Java side to print the stack as I'm unfamiliar with that code.\r\n\r\nFor now if the users wants to they can access the stack directly or pass in the property names on Error to JSON.stringify, see below\r\n\r\n{code}\r\nvar e = new Error('Some error');\r\n\r\n// Log all properties on Error\r\nconsole.log('e=' + JSON.stringify(e, Object.getOwnPropertyNames(e)));\r\n// gives [INFO] e={\"stack\":\"Error: Some error\\n at /app.js:1:20\\n at Module._runScript (ti:/module.js:596:17)\\n at Module.load (ti:/module.js:105:7)\\n at Function.Module.runModule (ti:/module.js:74:9)\",\"message\":\"Some error\"}\r\n\r\n// Log only stack\r\nconsole.log('e.stack=' + e.stack);\r\n// gives \r\n// [INFO] e.stack=Error: Some error\r\n// [INFO] at /app.js:1:20\r\n// [INFO] at Module._runScript (ti:/module.js:596:17)\r\n// [INFO] at Module.load (ti:/module.js:105:7)\r\n// [INFO] at Function.Module.runModule (ti:/module.js:74:9)\r\n{code}", "updateAuthor": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "created": "2018-03-23T20:01:08.000+0000", "updated": "2018-03-23T20:01:08.000+0000" }, { "id": "437621", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "It sounds like this behavior is actually according to the ES5 spec in V8.\r\n\r\nIf 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 a {{message}} property which is just the message passed in (so here it'd be {{'Some error'}}).\r\n{code:javascript}\r\nTi.API.error(error.stack);\r\n{code}\r\n\r\nWe 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\r\n and TIMOB-25965 (though I'm not sure they were updated to note the new property).\r\n\r\nSo, 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 the {{stack}} property if it's available, and fall back to the {{message}} property if not.\r\n\r\nBut we may want to alter our JSON.stringify impl on Android to specifically handle this case.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2018-05-14T17:18:13.000+0000", "updated": "2018-05-14T17:18:13.000+0000" }, { "id": "438452", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/10112", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-06-16T03:50:24.000+0000", "updated": "2018-06-16T03:50:24.000+0000" }, { "id": "441665", "author": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "body": "FR Passed.\r\n\r\n{{JSON.stringify(Error)}} returns the appropriate error & not {}.\r\n\r\nStudio Ver: 5.1.1.201809051655\r\nSDK Ver: 7.5.0 local build\r\nOS Ver: 10.13.5\r\nXcode Ver: Xcode 9.4.1\r\nAppc NPM: 4.2.13\r\nAppc CLI: 7.0.6\r\nDaemon Ver: 1.1.3\r\nTi CLI Ver: 5.1.1\r\nAlloy Ver: 1.13.2\r\nNode Ver: 8.9.1\r\nNPM Ver: 5.5.1\r\nJava Ver: 10.0.2\r\nDevices: ⇨ google Nexus 5 (Android 6.0.1)\r\n ⇨ google Nexus 6P (Android 8.1.0)\r\nEmulator: ⇨ Android 4.1.2\r\n", "updateAuthor": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-09-18T22:02:29.000+0000", "updated": "2018-09-18T22:02:29.000+0000" }, { "id": "441819", "author": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR Merged.", "updateAuthor": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-09-19T21:34:50.000+0000", "updated": "2018-09-19T21:34:50.000+0000" }, { "id": "442360", "author": { "name": "kmahalingam", "key": "kmahalingam", "displayName": "Keerthi Mahalingam", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Verified the fix on SDK 7.5.0.v20181004095510. Error returns correctly. Closing.\r\n{code}\r\nOperating System\r\n Name = Mac OS X\r\n Version = 10.13.6\r\n Architecture = 64bit\r\nNode.js\r\n Node.js Version = 8.9.1\r\n npm Version = 5.5.1\r\nTitanium CLI\r\n CLI Version = 5.1.1\r\nTitanium SDK\r\n SDK Version =7.5.0.v20181004095510\r\nDevice\t\t\t =Oneplus 5T Android 8\r\n\t\t\t\t\tPixel android 6 emulator \r\n{code}", "updateAuthor": { "name": "kmahalingam", "key": "kmahalingam", "displayName": "Keerthi Mahalingam", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2018-10-05T18:52:26.000+0000", "updated": "2018-10-05T18:52:26.000+0000" } ], "maxResults": 13, "total": 13, "startAt": 0 } } }