On-Device Debugging Part II: Timbeeeeeeer!

Image for post
Image for post
Photo by Arnaud Mesureur on Unsplash

Over the past year, my team have been steadily building a Developer Options screen for our app. It is a simple PreferenceScreen available on debug builds that aims to help us:

  • figure out what’s going on without needing to be attached to a computer

In this series of posts, I will share what these various options are and how we made them.

(If you are not familiar with PreferenceFragmentCompat, I highly suggest to read about that first before proceeding. You can start with this AndroidX guide on Settings.)

Read the other posts in this series:

One of the tools we utilise a lot at Woolworths is Timber. We use it not just to help us with debugging during development, but also to figure out problems early during testing as well as to keep an eye on things in production.

Before, when we have a build for testing and things don’t go to plan, we get sent a screenshot pretty much like this:

Image for post
Image for post
Uh 🙀

We try to figure out what they were trying to do before the app crashed, replicate the exact conditions they had prior, and try and try and try. More often than not, we hit the “that shouldn’t have happened” wall — even though it obviously just did. 🤦‍♀

To help in these situations, we turned to Timber. We log those “We should never get here!!!” scenarios using Timber.e. In production, those logs get sent to Fabric via Crashlytics.log(). In debug builds, those logs get sent to a crash log screen.

This screen shows the stacktrace, if there’s any, and some basic information about the build and the device. We also decided to use this screen to log any uncaught exceptions. At the bottom of the screen is a button to send the crash log through via an Intent Chooser.

Image for post
Image for post
Crash log screen variations

To bring this to life, we override Timber's e:

And printStackTrace simply passes on the information to a dedicated Activity that would display the error.

We provide the kind of error as an Intent extra with a CrashType:

The crash screen implementation is pretty straightforward, we retrieve the extras and use data binding to display the message and style the header. (For the curious, I previously wrote about using resource references in databinding)

Since we use the crash log screen for uncaught exceptions as well, we directly call the Activity when something goes wrong. This means that it skips the Timber processing but sometimes it's still useful to see the logs in Logcat, so we log the stacktrace there as well:

The “Send crash” button at the bottom of the screen sends out an ACTION_SEND Intent so that users can send the information via email, Slack, or whatever other app they choose (I also wrote about that here!).

This may seem like a simple thing, but time and again it has helped us quickly figure out issues in a more meaningful way. Even if those helping us test choose to send a screenshot, there is more relevant information rather than the generic crash dialog. 💞

Originally published at https://zdominguez.com on June 24, 2019.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store