Non-fatal crashes: the crash rate that matters

Almost every developer has some kind of crash monitoring set up for their app. And the most common metric they monitor for inferring the app's health is the crash rate.

But in a properly structured app, recoverable and non-recoverable exceptions are caught and displayed in a (hopefully) readable way to the user. Usually, the pattern is to handle all the known exceptions and have a generic message for any exception that you don't expect (read this for more on CoroutineExceptionHandler):

   val handler = CoroutineExceptionHandler { _, e ->        
    	when (e) {
            is ConnectionError -> showMessage("No internet")
            is ExpectedBackendError -> showMessage("Wrong input")
            else -> showMessage("Something went wrong")
        }
    }

As a user, I bet you encountered, at least once, when a generic error message such as Something went wrong, please try again later appeared when trying to accomplish something. Well, in my opinion, this is worst than a crash. You cannot accomplish your task, the app didn't crash so you are not sure if it's your fault or the app's broken, and there's no actionable thing to do (the try later part almost never works).

Therefore, the "real" crash rate I am looking for when evaluating the health of my apps (e.g. when deciding whether to increase the staged rollout percentage for a new version) is this non-fatal crash rate (or silent crash rate if you prefer). This shows the real experience of the users since even though the app didn't literally crash, an "unexpected" code path was executed which most of the time might be even worst.

Most popular crash reporting SDKs support these types of non-fatal crashes. For instance, with Crashalytics (maybe the most popular SDK?) you can easily record these exceptions like this (documentation):

Firebase.crashlytics.recordException(e)

So go ahead and monitor the silent crashes in your app. Hopefully, this will improve the experience for your users since you will know if an unexpected error happens and if this can be avoided in a future version.

Happy coding!