Search code examples
nativescriptangular2-nativescriptcrashnativescript-angularnativescript-plugin

NativeScript Hybrid Mobile App: Tracking/Capturing Crashes


I am building a NativeScript mobile app and among other things I am capturing for analytics purposes, I need to capture "app crashes" possibly with errors/reasons it crashed.

I came across this SO post but there it was in the response of a question on how not to let the app crash. Following was suggested to catch crash events:

var application = require("application");

application.on(application.uncaughtErrorEvent, function (args) {
    if (args.android) {
        // For Android applications, args.android is an NativeScriptError.
        console.log("NativeScriptError: " + args.android);
    } else if (args.ios) {
        // For iOS applications, args.ios is NativeScriptError.
        console.log("NativeScriptError: " + args.ios);
    }
});

If I go by the above then I have the following questions. Would appreciate if somebody can confirm if this means every-time the app is crashing it will generate this application.uncaughtErrorEvent event? Can I rely on it? If it is true then maybe I can make a REST call to my backend and store date, time and whatever is in args.android or args.ios.

If above is not the correct way then can somebody please help me on how to go about doing this?

Any help is highly appreciated. Thank you!


Solution

  • The application.onUncaughtError will be hit probably 95-98% of the time during a crash; it is pretty reliable. I have seen the app crash without any notice at all it just goes poof, but I'm not sure any reporting system can handle that one.

    The way I do it is during the app startup I register a couple things:

    1. I create a global.error function; this is used for anything (like try/catch, promise/catch) that needs to send the errors through to be logged remotely. So anywhere in my codebase I can do a global.error(theError); and it will be handled; this way I do NOT have to worry about trying to load or require things while an error is taking place, as that can cause other errors.
    2. I use the onUncaughtError event to catch anything that is not normally caught, and then notify the user that an error has occurred and quit the app. (in this case, trying to recover is not recommended as you have no idea where the error was thrown from...)
    3. If I use a worker thread, When I startup a worker I register the worker.onerror to forward its data to the main threads global.error function AND I have a specific message from the workers' version of the global.error that sends the error back to the primary thread. This way if the worker itself calls global.error that message is passed back to the main thread and then to the global.error on the main thread which handles everything properly.

    This technique allows me to catch pretty much all errors that can occur. The main global.error function and the onUncaughtError both use a simple reporting library that I built that reports all the data back to one of my servers, IF the device is online. If the device is offline, it can optionally save the data to a reporting file to be uploaded later; or just ignore it.

    It also has safety checks to verify the error isn't a network error (we don't want the error reporting to go into a loop, i.e. trying to report the error causes an error, which then tries to report the error; so in the event it is a certain type of network error; it will ignore those. )