How to set up fatal error logging with Sentry

I’ve followed the different steps in order to set up Sentry logging for my Expo app. It works as long as I use Sentry.captureException to capture the exceptions. However, I’d like to capture all fatal errors (i.e. those that are displayed in redbox in the Expo client). I especially want to be able to do this in production mode.

Does anyone know how? I’ve tried using the method outlined here using ErrorUtils, but I can’t seem to use a custom error handler.

Does anyone have any idea on how to achieve this?

Wait…I thought Sentry does this out of the box…no additional configuring needed? Any errors/exceptions (including unahndled/uncaught ones) will trigger a Sentry report.

This has been my experience at least with using Sentry.

Are you sure? Are you using it with React Native / Expo? Because you’re right when it comes to using sentry client in a web browser, because it’s been built for that. In node.js for example, you have to configure it to specifically handle uncaught exceptions.

Doesn’t work for me in Expo anyways…

I feel like I get Sentry reports for unhandled errors/exceptions, so yeah I’d say it is working for me.

Interesting… Would you mind sharing how you’ve implemented Sentry in React Native?

It’s been several months since I set everything up, but I followed the docs here

I know I get sentry reports for errors that I am not otherwise handling in say a try/catch

@insats - did you ever get this figured out? I seem to be having the same issue.

Not really not. It seems to be working as long as debug is set to true in the config object. But there are still fatal crashes occurring for users that don’t seem to get captured…

It turns out that Expo’s Sentry integration is for JavaScript code only, so if there’s a crash/unhandled exception in native code, Sentry doesn’t see it.

The above link mentions Fabric Crashlytics (for standalone Android apps), but that’s deprecated. I think there’s a chance that Firebase Crashlytics will work, but I am probably missing something.

EDIT: I’ve been told that you’d have to eject to use Firebase Crashlytics.

Actually. It seems to have stopped working now again. I have no idea why it sometimes works and sometimes doesn’t. @wodin I’m not talking about native errors.

Are you sure?

e.g. if you try to render the following (string instead of number in style) it will crash in native code and Sentry will not see it:

<View style={{padding: "10px"}}>...</View>

Also, an OTA update where the bundle does not finish downloading before the user kills the app can cause crashes in native code like this:

And there’s currently an issue affecting SDK 36 where users using dark mode on Android get crashes in native code like this:

I see, well, in my case, if for example try to call a function that doesn’t exist, javascript will throw an error, but Sentry doesn’t pick it up. i.e:

Sentry.init({
  dsn: config.sentry.dsn,
  enableInExpoDevelopment: true,
  debug: true
})

foo() // Does not exist

As far as I know, the above code should cause an error to be sent to Sentry. But that doesn’t happen for me. The settings are correct, I can send errors manually using Sentry.captureMessage, Sentry.captureException etc.

OK, yes, I would expect that to work. Maybe I will have a chance to try Sentry tomorrow or next week. I’ll let you know if it works for me.

Were you guys able to figure out this problem? I am having the same issue. Like when I pass a null to a function call when it’s expecting a number, it throws an error but is not captured in Sentry.

I’m pretty sure that everything is working for me now, but I can’t recall exactly what I changed. I think the debug variable was important but I’m not sure. In my case, I also had a lot of errors that got swallowed by MobX reactions.

I’ve since moved from Expo to the Bare Workflow so I’m not using the expo-sentry package anymore.

Thanks for the quick response. I have the debug set to true. Sentry also throws a fatal error when it is not able to report the error through “catchexception” because of poor internet connection. Like logging errors through Sentry can in a way crash your app when there is no internet too.

Oh, that’s a good catch… Hmm, so wrapping Sentry and using some kind of connection control first might be a good idea then. I’m already using a wrapper, like so:

import config from '../../config'
import * as Sentry from '@sentry/react-native'

const sentryEnabled = config.sentry && config.sentry.dsn || false

if (sentryEnabled) {
  Sentry.init({
    dsn: config.sentry.dsn,
    enableInExpoDevelopment: true,
    debug: true
  })
}

const logger = {
  info: function (...args) {
    if (sentryEnabled) {
      Sentry.captureMessage(args[0])
    } else {
      console.log(...args)
    }
  },
  error: function (...args) {
    if (sentryEnabled) {
      Sentry.captureException(new Error(args[0]))
    } else {
      console.error(...args)
    }
  }
}

export default logger

Would be easy to expand upon.

:man_facepalming:

That’s true. Like we can check for internet availability through this “expo-network” package. But the issue still becomes, how do we still submit an error even after checking for connection and not having one. Like how do we manage retries on poor network.

Feels like it should be part of Sentry where it checks and retries error submission instead of fatal errors.

Wouldn’t actually be very hard. Could use AsyncStorage to store errors if offline. When the app starts you could send all unsent errors and clear them from storage.