Mobile Error Handling

פורסם ב: 16 בנובמבר 2017 by עידית משען

Mobile Error Handling Guide:

Mobile error handling has always been a difficult thing to tackle. Many issues arise and not always it is clear
how to correctly handle them.

Which errors to catch? What to display to the user (general message, detailed exception, short message)?
how and where to log errors and also what to do when an error occurred.

Mobile applications provide even a greater challenge because the network state is more susceptible to
failures and most applications are heavily depended on it.

Not only that, contrary  to web application, in mobile applications the majority of the code is running
on the user device (as opposed to a centralized server). There are hundreds of device configurations
(device models and os versions) and the need to know that an error occurred  on user devices is critical
for your app success. You need to know about common crashes of your application as it goes out to the
world and fix them, otherwise you are in the dark.

You created the best-app-out-there that you tested on some devices and user flows, but when it goes to
the outside world issues will arise, guaranteed. And you want to know about those issues, fix them and get
a new app to the different stores.

This article was meant to guide you through the process and give you guidelines on how to handle errors
in your mobile application.

What not do

 Before we discuss how to correctly handle errors, we should discuss what not to do.

If you ever find yourself writing a try catch block and write the exception to some local log you are doing
the worst thing that you can possibly do because you are not telling the user that his operation failed and
he is completely in the dark. The user activated some function in your app and you are not giving him feedback that his operation failed nor do you tell him why. You simply ignore him.

Consider you go to your favorite shoe store asking the salesperson to bring you Nike size 36.
The salesperson goes to the back of the store and never comes back. Can you imagine your frustrations?
Sitting there waiting for your shoes not knowing what to do?

This is how your app users will feel.

If you are also calling a network function and on the on failure of your network library, you are simply not doing
anything or write the error to some log, you are not doing the right thing

Not only that, you as the application owner, did not know that an error occurred. This error probably occurred
for other users and you cannot fix it.

Implementing an error handling strategy

Let’s get to the hard core of the issue. Our goals are

  1. Build a strategy to log application errors to the server
  2. Build a strategy on how to handle network errors
  3. Build a strategy to display errors to the user

Log errors to the server

Let’s start with the easy part that most of you probably already do. You need a mechanism to log application
errors to a server. You want to log them to a server in order to monitor those errors and fix them.

Logging unexpected errors

You want to be able to log unexpected errors (errors that you did not have a specific error catching handlers).
Those errors will most likely crash your application, but at least you want to know that they occurred to fix them.

You also want to log expected errors (errors that you are anticipating will occur, but you still want to know that
they occurred (i.e network errors like timeout, but not only).

Luckily, we have 3rd party libraries that will do just that. Take a look at Firebase, ACRA, Crashlytics and many many more.
It is really up to you to decide which one to choose.

I will not guide you on how to install them (typically a few minutes installation and off you go.

As soon as you implement crash reporting, unexpected errors in your application will automatically be recorded
to the server and you will have the tools (provided by the crash reporting platform ) for you to analyze them
including slice and dice the errors based on platform, device, OS version etc…

Logging expected errors

Typically a good crash reporting service will also provide you with the ability to report expected errors to the server.

Errors that you are anticipating will occur and report them to the server. For example, assuming you are depended on an external weather API that could return to you data structure that you are not anticipating.
Since you did not write the service, you know that it is possible. Thus you want to log the incident to the crash
reporting service.You want to log the request and the response from the weather API(as well as a user id ?)
to your crash reporting service such that you can track and fix the issue.

This is an amazing tool for you.

Logging Network Errors

What about network errors? Network errors requires a special attention because those are the majority of the
expected errors. We all know that mobile applications are susceptible to network issues (coverage, phone state etc,
quota etc.) .

If you are using a network library to access your application server you know that there could be network errors.
Typically you will get them as part of an OnFailure callback api (depending on the network library that you are using).

You could get:

  • Local network error (phone connectivity issues)
  • A mobile provider network issues
  • your application server network issues (SSL, server load, server down etc)

So should you log network errors to the server? for those of you that are giggling and asking how is it possible to log
errors to the server while there are network issues, you should know that a good crash reporting service will queue
the log and send it as soon as network state is restored and the app was restarted.

And thus, this is one of the reason why you should not log network errors to the server. After all, what is the point to
get reports on a network error that occurred in the past and is already fixed?

No only that, do you really want to know that a mobile user out there had a bad network coverage or a network failure?

What about network errors that are related to your application server? Should you log those errors?
My view is typically not because you probably implemented a monitoring on your application server and you already know that you have a server issue before it was reported by users.

I may be wrong, but I can not think of of good scenario that make sense to log a network error related to your server
other than for debugging purposes (for example a specific network call that sometimes take longer than expected).

What to show to the user?

 Ha, now comes the hard part and probably controversial. What to show to the user?  The following are my 2 cents
and you can take it to any direction you want to.

We are talking about displaying expected error of course as unexpected errors will most likely crash the app.

So, my point of view that any expected error should be reported to the user and the error is a generic error.

If the expected error is None network error, you may want to show something like “Application failure please try again.
If the issue persists, please report to support@myserver.com”. But, I really leave it up to you.

However when a network error occurred, there could be 2 use cases and you probably want to display a different error
for each use case.

  1. If this a generic network error, you should display “General network error. Please check your phone network
    connectivity and try again later”
  2. If this is your application server error, you should display “Application server error please try again.
    If the error persists, please contact support@myserver.com

I leave it up to you to distinguish between the 2 cases. I typically ping a well known high end server and if the ping is successful I know I have an issue with my application server. Otherwise, it is a general network error of the phone
or the provider. Simple yet effective.

How to show the error to the user

Again, i leave it up to you. I typically like to display a small view on the top of my current screen overlaying the UI.
Of course this view needs to be dismissed somehow, otherwise, it will stay on the screen.
I recommend dismiss it by clicking on it or by executing any other user action. Here is an example of such a view…

Reporting the error to the current screen

Sometimes it is a tedious process to report errors to the current screen. The error occurred few levels down
the call stack and you need to report the error to the user.

I like to use EventBus to report such errors (an event publish/subscribe library). This makes it easier to report errors
across components.

Reversing the UI

Another issue to consider is the UI. Let’s take for example a user trying to delete a post from a feed.
Typically, you would fire off a network call to delete the post and remove the post from the UI.
Now, suppose the network call  reported an error?

You want to show the post again to the user (after all the operation failed and you want to let the user try it again).

You can argue that you should delete the post only if the network call was successful… You can.
It will make a safe app, but not a responsive and user friendly one.

Summary

This article is not bullet proof and definitely not the bible on how to handle errors correctly. But I hope it makes
you think about it and refine your strategy for handling error.

Happy coding..