Error Handling on Android

163
Bugsnag
Bugsnag automatically detects errors in your mobile, front-end, and back-end applications. It gives your team the tools to fix things fast. 3,500 engineering teams such as Square, Shopify, and Airbnb use Bugsnag.

This post is by Jamie Lynch of Bugsnag


How many times have you been in the middle of using a new shiny app, only to have it crash on you?

This is the first in a series of posts that will investigate how the exception handling mechanism works in Java and Android, and how crash reporting SDKs can capture diagnostic information, so that you're not flying blind in production.

How do exceptions work for JVM and Android apps?

Exceptions should be thrown in exceptional circumstances where the calling code needs to decide how to recover from an error condition.

What is an Exception object?

A Throwable is a special type of object which can be thrown and alter the execution path of a JVM application. For example, the code snippet below throws an IllegalStateException:

fun main() {
   try {
       throw IllegalStateException()
       println("Hello World")
   } catch (exc: Throwable) {
       println("Something went wrong")
   }
}

Throwing an exception means that the execution flow changes, and 'Hello World' is never printed. Instead, the program counter will jump to the nearest catch block, and executes the error recovery code within, meaning our program prints ‘Something went wrong’ instead.

Of course, it doesn't always make sense to recover from a failure — for example, if an OutOfMemoryError is thrown by the JVM, there is very little prospect of ever recovering from this condition. In this case it makes sense to leave the Throwable as unhandled, and allow the process to terminate so the user can restart the app from a fresh state.

Anatomy of the Throwable class

Throwable has two direct subclasses: Exception, and Error. Typically an Error is thrown in conditions where recovery is not possible, and an Exception where recovery is possible. Additionally, there are many subclasses of Exception which convey additional meaning — for example, an IllegalArgumentException would indicate the programmer passed an invalid argument, and an IllegalStateException would indicate that the program encountered an unanticipated state.

fun main() {
   try {
       throw IllegalStateException("This should never happen!")
       println("Hello World")
   } catch (exc: Throwable) {
       println("Something went wrong")
   }
}

Let's consider the above snippet again. The constructed IllegalStateException object captures a snapshot of the application at the time of the error condition:

java.lang.IllegalStateException: This should never happen!
    at com.example.myapplication.Exceptions101Kt.foo(Exceptions101.kt:12)
    at com.example.myapplication.Exceptions101Kt.main(Exceptions101.kt:5)
    at com.example.myapplication.Exceptions101Kt.main(Exceptions101.kt)

This is commonly called a stacktrace. Each line represents a single frame in the application's call stack at the time of the error, which match the filename, method name, and line number of our original code snippet.

A stacktrace can also contain other useful information, such as program state, which in this case is a static error message, but we could equally pass in arbitrary variables.

Exception handling hierarchy

After throwing an exception, an exception handler must be found to handle the exception, or the app will terminate. In the JVM, this is a well-defined hierarchy, which we'll run through here.

First up in the exception handling hierarchy is a catch block:

try {
   crashyCode()
} catch (exc: IllegalStateException) {
   // handle throwables of type IllegalStateException
}

If a catch block isn't available in the current stack frame, but is defined further down the call stack, then the exception will be handled there.

Next in the hierarchy is implementations of UncaughtExceptionHandler. This interface contains a single method which is invoked whenever a Throwable is thrown, after the handler has been set:

val currentThread = Thread.currentThread()
currentThread.setUncaughtExceptionHandler { thread, exc ->
   // handle all uncaught JVM exceptions in the current Thread
}

It's possible to set an UncaughtExceptionHandler in a few different places; the JVM has a defined hierarchy for these. First, if a handler has been set on the current Thread, this will be invoked. Next up will be a handler on the ThreadGroup, before finally, the default handler is invoked, which will handle all uncaught JVM exceptions by printing a stacktrace, and then terminating the app.

Thread.setDefaultUncaughtExceptionHandler { thread, exc ->
   // handle all uncaught JVM exceptions
}

It's the default UncaughtExceptionHandler that is most interesting from an error reporting point-of-view, and it's the default UncaughtExceptionHandler that is responsible for showing that all too familiar crash dialog on Android.

The UncaughtExceptionHandler interface is the building block of all crash reporting SDKs on the JVM, such as bugsnag-android or bugsnag-java. Read on in part two to learn how we can define a custom handler for uncaught exceptions, and use it to create a crash reporting SDK.

Error handling on Android

Bugsnag
Bugsnag automatically detects errors in your mobile, front-end, and back-end applications. It gives your team the tools to fix things fast. 3,500 engineering teams such as Square, Shopify, and Airbnb use Bugsnag.
Tools mentioned in article
Open jobs at Bugsnag
Front End Software Engineer
San Francisco, CA
Bugsnag gives engineering teams the tools and workflow they need to focus more on shipping software and less on fixing bugs. We help teams take a proactive approach to software quality, translating their errors into action. Thousands of companies like Square, GitHub, Shopify, and Pandora use Bugsnag as a daily dashboard to ship web, mobile, and desktop apps that can evolve with the pace of their business. Our front-end dashboard application and static sites are some the main ways our customers interact with Bugsnag. Our team is growing and we're taking on bold, new challenges everyday. We'd love to see what we can do next with your help.
  • React — our main customer-facing dashboards are built using React
  • Reflux.js — we follow the Flux architecture for data flow in our dashboard
  • Ruby on Rails — our dashboard APIs are powered by Rails
  • Sass — clean, componentized CSS built with Sass/scss is used on all of our sites
  • D3.js — we use d3 to graph error data in our dashboard
  • ES6 with babel — we're JavaScript fans who like to be able to test out the latest JS features
  • Webpack — we're using the Webpack module bundler for our dashboard assets
  • Many more — we're a polyglot company, detecting errors on every platform
  • Implement user interfaces and features in Bugsnag’s products and marketing properties
  • Create elegant, reusable front-end components that work within complex web applications
  • Collaborate with product designers, marketers, and other software engineers to deliver great user-facing products and experiences
  • A passion for building compelling user-facing products and beautiful websites
  • Strong HTML/CSS experience, including concepts like layout, specificity, cross browser compatibility, and accessibility
  • JavaScript experience, including concepts like asynchronous programming, closures, types, and ES6. Experience with React a strong plus.
  • Experience working with native browser APIs and optimizing front end performance
  • A willingness to dive into new technologies and solve unfamiliar problems as the need arises
  • Ruby/Rails development experience is a plus
  • At least 1-2 years of professional experience writing production-ready front end code
  • We value ownership, learning, and personal development.
  • We're building a strong culture of transparency and honesty.
  • We have a beautiful office in downtown San Francisco.
  • We have a safe and inclusive work environment.
  • We offer great benefits: lunch on us every day, medical, dental, vision, 401k matching, commuter stipend, annual conference attendance, and your choice of Apple hardware.
  • Senior Platforms Engineer
    San Francisco, CA
    We are looking for a new platforms engineer to help deliver an amazing experience to our customers while contributing back to the open source community. Our open source libraries support detecting crashes and capturing diagnostic data in several programming languages and frameworks. This position involves working with a variety of programming languages and development environments to build new features, help customers troubleshoot problems, review contributions to our open source libraries, and generally make developers’ lives easier.
  • You will develop and document new features in our open source libraries to expand the development platforms supported by Bugsnag.
  • You will test and update libraries to work with the evolving software ecosystem, such as the web frameworks, analytics SDKs and other libraries customers may be using at the same time as a Bugsnag integration.
  • You will troubleshoot issues reported by customers via GitHub issues, improving documentation based on common patterns.
  • You will go to software development conferences to keep up with best practices and new technologies, answer customer questions, and receive feedback on using the product and libraries.
  • You will build tools to make support and maintenance easier, like automating common tasks and interactions.
  • You love working in multiple different technologies and programming languages.
  • You can spend a few weeks learning a new platform, and feel proficient in helping others to troubleshoot installation instructions and syntax errors.
  • You have a personable, empathetic and professional manner when dealing with customers.
  • You have experience in C, Objective-C, Ruby, or React Native are a plus.
  • We value ownership, learning and personal development
  • We have a strong culture of transparency and honesty
  • We have a safe and inclusive work environment
  • Pick your own hardware (Thunderbolt display, top-end MacBook Pro, whatever you need)
  • Great benefits (medical, dental, vision, 401k, commuter stipend, conference attendance)
  • Lunch on us every day
  • Platforms Engineer
    San Francisco, CA
    Bugsnag helps teams focus on building better software by providing automated crash monitoring for web, mobile, desktop, and server apps. Currently, half of a typical developer’s time is spent finding and fixing bugs; we aim to bring that number as close to zero as possible by automating the entire monitoring process and allowing developers to focus their time on feature development. To do this, we give our users instant visibility into where their code is not executing as expected, we then measure these errors, collect all related data, and give our users the information they need to understand which software issues really matter and need fixing. Launched in February 2013, Bugsnag processes hundreds of millions of crashes per day for over thousands of developers at companies like Airbnb, Lyft, Square, and Shopify. Headquartered in San Francisco, California we have a small team of 28 employees and growing! We are looking for a new platforms engineer to help deliver an amazing experience to our customers while contributing back to the open source community. Our open source libraries support detecting crashes and capturing diagnostic data in several programming languages and frameworks. This position involves working with a variety of programming languages and development environments to build new features, help customers troubleshoot problems, review contributions to our open source libraries, and generally make developers’ lives easier.
  • You will develop and document new features in our open source libraries to expand the development platforms supported by Bugsnag.
  • You will test and update libraries to work with the evolving software ecosystem, such as the web frameworks, analytics SDKs and other libraries customers may be using at the same time as a Bugsnag integration.
  • You will troubleshoot issues reported by customers via GitHub issues, improving documentation based on common patterns.
  • You will go to software development conferences to keep up with best practices and new technologies, answer customer questions, and receive feedback on using the product and libraries.
  • You will build tools to make support and maintenance easier, like automating common tasks and interactions.
  • You love working in multiple different technologies and programming languages.
  • You can spend a few weeks learning a new platform, and feel proficient in helping others to troubleshoot installation instructions and syntax errors.
  • You have a personable, empathetic and professional manner when dealing with customers.
  • You have experience in C, Objective-C, Ruby, or React Native are a plus.
  • We value ownership, learning and personal development
  • We have a strong culture of transparency and honesty
  • We have a safe and inclusive work environment
  • Pick your own hardware (Thunderbolt display, top-end MacBook Pro, whatever you need)
  • Great benefits (medical, dental, vision, 401k, commuter stipend, conference attendance)
  • Lunch on us every day
  • Platforms Engineer, Front-end
    Bath, UK
    We are looking for a software engineer to help deliver an amazing experience to our customers while contributing back to the open source community. Our open source libraries support detecting crashes and capturing diagnostic data in several programming languages and frameworks. This position involves working with browser based development environments to build new features, help customers troubleshoot problems, review contributions to our open source libraries, and generally make developers’ lives easier.
  • You will help maintain the Bugsnag libraries for browser javascript
  • You will test and update libraries to work with the evolving software ecosystem, such as front-end frameworks (Angular, React, Ember etc), analytics SDKs, and other libraries customers may be using at the same time as a Bugsnag integration
  • You will develop and document new features in our open source libraries to expand the development platforms supported by Bugsnag
  • You will troubleshoot issues reported by customers via GitHub issues, improving documentation based on common patterns
  • You will go to software development conferences to keep up with best practices and new technologies, answer customer questions, and receive feedback on using the product and libraries
  • You will improve the end to end experience of using our javascript library to monitor some of the biggest websites in the world
  • You love working in multiple technologies and programming languages
  • You have experience in developing in Javascript
  • You have a personable, empathetic and professional manner when dealing with customers
  • You have a minimum of 3 years of experience as a software engineer
  • Experience with various front-end frameworks and build systems a plus
  • Experience with node.js a plus
  • We value ownership, learning, and personal development.
  • We're building a strong culture of transparency and honesty.
  • We have offices in downtown San Francisco and central Bath.
  • We have a safe and inclusive work environment.
  • We offer great benefits: lunch on us every day, pension contributions, private medical insurance, company sponsored tech conference attendance, and your choice of Apple hardware.
  • We offer all new Bath hires a trip out to San Francisco to meet the team.
  • Verified by
    Sr. PMM
    Co-founder and CEO
    Senior Growth Marketing Manager
    You may also like