Monitoring errors in Xamarin apps

Monitoring errors in Xamarin apps

December 20th, 2018 • By Jason Skowronski

Xamarin is based on Mono, the open source implementation of Microsoft's .NET Standard. It allows us to create apps that easily run in multiple devices like phones and smart watches. It solves the difficulties many developers face when they’re developing cross-platform apps like different coding languages and UI paradigms. With Xamarin, you can use C# as a single language for iOS, Android, and Universal Windows apps.

Apps freezing, crashing, or slowing down are the top reasons for a bad review. According to a survey by Dimensional Research, 49 percent of users expect mobile apps to start within two seconds. If an app crashes, freezes, or has errors, 53 percent of users will uninstall it. These problems not only cause existing users to delete your app, but they can also discourage new users from downloading your app. That’s why having visibility into the performance of mobile apps in real time and from real users is so critical—it helps identify customer problems and create great user experiences.

We will show you how to handle errors using both native error handling in Xamarin and using Rollbar, which is a dedicated service for remote error monitoring. Below, you can see we’ve created an example app that triggers an exception when the user clicks on a button. The error message will be tracked by Rollbar, including a stack trace where you can see the line of code that caused the error. Rollbar captures errors that occur anywhere in the app.

Native error handling in Xamarin

The basic way to catch errors in Xamarin apps is by using a try/catch block. When an error is thrown in the try block, the catch block executes and handles the error. For example, you may want to report the error to a tracking service like Rollbar.

try {
  int x = 0;
  x = 1 / x; // Divide by zero error
} catch (Exception ex) {
  Console.WriteLine(ex);          
}

In real life, these try/catch blocks often omitted because errors pop up in unexpected places. Thankfully, most modern programming frameworks have built-in hooks for dealing with uncaught exceptions. The AppDomain.CurrentDomain.UnhandledException event is one of the hooks built into any .NET Standard implementation. It allows handling of any unhandled exception within the current AppDomain. Consider it as a "handle it all last chance error sink".

In Xamarin Forms, this hook allows you to track the error, display a message to the user, or attempt to recover. You can see an example below:

AppDomain.CurrentDomain.UnhandledException += (sender, args) => {
  System.Exception ex = (System.Exception)args.ExceptionObject;
  Console.WriteLine(ex);
};

In addition to the .NET Standard hooks, platform extensions provide similar hooks. For example, the Android specific AndroidEnvironment.UnhandledExceptionRaiser event serves similar purpose as the AppDomain one, but provides better debugging information about the same error. To get more detailed exception information, we can write some platform-specific code. This code goes into the project generated for each platform.

AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) => {
  var newExc = new ApplicationException("AndroidEnvironment_UnhandledExceptionRaiser", args.Exception);
};

Writing errors to the console works fine during development, but there is no way to track these errors centrally after your app is installed. Even if you log the errors into a local log file - it stays on your users personal devices. Tracking errors is essential to see how many of your users are affected by errors, and to prioritize fixes to critical ones. Wouldn't it be nice to have a way of monitoring these errors remotely close to real time while observing their real scope and impact as they happen so you can react quickly and appropriately?

Add Rollbar error monitoring

Rollbar’s .NET SDK allows you to track and resolve errors that occur in your Xamarin cross-platform applications after release. It gives you a live error feed from your application, along with complete stack traces and contextual data to debug errors. On the backend, it lets you track the environment the error is coming from (prod or staging), the server that generated the error, and the user’s session data. You can then assign the ownership of errors to your team and track when they are fixed. Learn more about Rollbar’s product features for Xamarin.

Now that you understand how to create global error handlers in Xamarin, we’re going to show you how to integrate Rollbar’s .NET SDK in your code. We've created a small sample app for Xamarin or you can add Rollbar to your own code.

Video of Xamarin errors in Rollbar

Step 1. Visit https://rollbar.com and sign up for an account if you haven’t yet. Next, create your project and select .NET from the list of SDKs. Save the server side access token that is generated for you. You’ll need this to configure Rollbar in the steps below.

Step 2. Install the Rollbar using NuGet Package Manager. You can install Rollbar using the Package Manager Console or in Manage NuGet Package for solution. You can find both options in Visual Studio under Tools->NuGet Package Manager; search for "Rollbar"

Screenshot of Rollbar Nuget

Alternatively, to install from the console, run the command below:

Install-Package Rollbar

Step 3. We've designed RollbarHelper.cs to make it easier to wire up Xamarin apps. Copy the file and add it under {root}/{appname}.Xamarin.Forms. Next, find the ConfigureRollbarSingleton() method in RollbarHelper and update it with the access token you received in step 1.

public static void ConfigureRollbarSingleton()
{
  const string rollbarAccessToken = "POST-SERVER-ACCESS-TOKEN";
  const string rollbarEnvironment = "production";
  // minimally required Rollbar configuration
  var config = new RollbarConfig(rollbarAccessToken) {
    Environment = rollbarEnvironment,
      ScrubFields = new string[]
      {
        "access_token",
        "Username",
      }
  };
  // minimally required Rollbar configuration:
  RollbarLocator.RollbarInstance.Configure(config);
}

Step 4. Next, add a global error handler in the Android and iOS projects. For Android, find MainActivity in the Android codebase and add the code snippet below in the OnCreate() method.

protected override void OnCreate(Bundle bundle)
{
  // Rollbar notifier configuartion
  RollbarHelper.ConfigureRollbarSingleton();

  // Registers for global exception handling.
  RollbarHelper.RegisterForGlobalExceptionHandling();

  AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) =>
  {
    var newExc = new ApplicationException("AndroidEnvironment_UnhandledExceptionRaiser", args.Exception);
    RollbarLocator.RollbarInstance.AsBlockingLogger(TimeSpan.FromSeconds(10)).Critical(newExc);
  };

  TabLayoutResource = Resource.Layout.Tabbar;
  ToolbarResource = Resource.Layout.Toolbar;
  base.OnCreate(bundle);
  global::Xamarin.Forms.Forms.Init(this, bundle);
  LoadApplication(new App());
}

For iOS, you can add code like this in your AppDelegate.cs.

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
  // Rollbar notifier configuartion
  RollbarHelper.ConfigureRollbarSingleton();

  // Registers for global exception handling.
  RollbarHelper.RegisterForGlobalExceptionHandling();

  // Rest of your code
  global::Xamarin.Forms.Forms.Init();
  LoadApplication(new App());
  return base.FinishedLaunching(app, options);
}

Send test errors

To test if it’s working, create a page that will generate an error message. In the example below, you can generate an error by clicking the "Crash me with an uncaught exception" button.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  xmlns:local="clr-namespace:App2"
  x:Class="App2.MainPage">

  <StackLayout>
    <Button Text="Crash me with an uncaught exception"
      VerticalOptions="CenterAndExpand"
      HorizontalOptions="Center"
      Clicked="Generate_Uncaught" />
  </StackLayout>
</ContentPage>
namespace App2 {
  public partial class MainPage : ContentPage {

    public MainPage() {
      InitializeComponent();
    }

    private void Generate_Uncaught(object sender, EventArgs e) {
      string value = null;
      if (value.Length == 0) {// <-- Causes exception
        Console.WriteLine(value);
      }
    }
  }
}

When you click the "Crash me with an uncaught exception" button, it will trigger the Generate_Uncaught() method. In this method, we have added a bug that is throwing System.ApplicationException:AndroidEnvironment_UnhandledExceptionRaiser.

Viewing errors in Rollbar

To view errors in Rollbar, you need to look into your account’s item page. The page will show you what these errors look like in Rollbar. The error we just generated should be called System.ApplicationException:AndroidEnvironment_UnhandledExceptionRaiser.

Screenshot of Rollbar Xamarin error item

Get more details by clicking on the item. You can now see a traceback showing you the exact source code file, method, and line number that generated the error.

Screenshot of Rollbar error item detail

Conclusion

Xamarin is an all-in-one solution for mobile development. You can build, test, distribute, and monitor your apps for a variety of platforms with just one tool. Rollbar provides a lot of contextual information that will help you troubleshoot and debug errors quickly. Now you know how to catch exceptions in Xamarin applications, and how easy it is to set up Rollbar. Learn more in our documentation for .NET, and sign up for a free trial today!

Get the latest updates delivered to your inbox.