Skip to main content

๐Ÿ› Error Tracking with Sentry

Shipnative integrates Sentry for real-time error tracking and performance monitoring. This guide will help you set up Sentry to proactively identify, diagnose, and resolve issues in your application.

Sentry Project Setup

1. Create Your Sentry Project

If you havenโ€™t already, create a new project on the Sentry platform:
  1. Go to https://sentry.io/ and sign up.
  2. Create a new project, selecting โ€œReact Nativeโ€ or โ€œReactโ€ as your platform.

2. Obtain Your DSN

Once your project is ready, youโ€™ll need your Data Source Name (DSN):
  1. In your Sentry project dashboard, navigate to Project Settings > Client Keys (DSN).
  2. Copy your DSN.

3. Configure Environment Variables

During the yarn setup process, you were prompted to enter this credential. If you skipped this or need to update it, you can manually add it to your apps/app/.env file:
EXPO_PUBLIC_SENTRY_DSN=your_sentry_dsn_here
Mock Mode: If this environment variable is not set, Shipnative will automatically use a mock Sentry service, allowing you to test error capturing without sending data to a live Sentry server.

Using Sentry in Your App

Shipnative provides a convenient useAnalytics hook (which includes error tracking functionality) and utility functions for interacting with Sentry. The useAnalytics hook (found in apps/app/app/hooks/useAnalytics.ts) includes a trackError function.
import { useAnalytics } from '@/hooks/useAnalytics'
function MyComponent() {
  const { trackError } = useAnalytics()
  
  // Example: Catch and track an error
  const handleError = (error: Error) => {
    trackError(error, {
      tags: { component: 'MyComponent', action: 'data_fetch' },
      extra: { userId: 'user-123', apiEndpoint: '/api/data' },
    })
  }
  
  // Simulate an error
  const simulateError = () => {
    try {
      throw new Error("Something went wrong in MyComponent!");
    } catch (error) {
      handleError(error as Error);
    }
  }
  
  return (
    <View>
      <Button onPress={simulateError} title="Trigger Error" />
    </View>
  )
}

Using Utility Functions

For direct error tracking or logging outside of React components, you can use the utility functions:
import {
  trackError,
  trackMessage,
  addBreadcrumb,
  setUserContext,
  clearUserContext,
  setTags,
  setExtras,
} from '@/utils/analytics'import { BreadcrumbCategories } from '@/types/errorTracking'
// Track an error
try {
  // some risky code
} catch (error) {
  trackError(error as Error, {
    tags: { screen: 'HomeScreen' },
    level: 'error',
  })
}

// Log an informational message
trackMessage('User completed onboarding', 'info')

// Add a breadcrumb
addBreadcrumb({
  category: BreadcrumbCategories.NAVIGATION,
  message: 'Navigated to Settings',
  type: 'navigation',
})

// Set user context
setUserContext({ id: 'user-123', email: 'user@example.com' })

// Clear user context
clearUserContext()

// Set tags
setTags({ environment: 'production', version: '1.0.0' })

// Set extra context
setExtras({ device_info: { model: 'iPhone', os: 'iOS' } })

Direct Sentry Client Access

For advanced usage, you can directly access the Sentry client instance:
import { sentry } from '@/services/sentry'
sentry.captureException(new Error('Something went wrong directly via Sentry client'))
sentry.captureMessage('Info message directly via Sentry client', 'info')
sentry.setUser({ id: 'user-456', email: 'test@example.com' })
sentry.addBreadcrumb({
  message: 'User performed action',
  category: 'ui',
  level: 'info',
})

Key Sentry Features

Exception Tracking

Automatically or manually capture unhandled exceptions and errors.
try {
  // risky code that might throw
  throw new Error("Failed to process payment!");
} catch (error) {
  trackError(error as Error, {
    tags: {
      component: 'PaymentForm',
      action: 'submit',
    },
    extra: {
      paymentMethod: 'credit_card',
      amount: 99.99,
    },
    level: 'error', // 'fatal', 'error', 'warning', 'info', 'debug'
  })
}
For more details on capturing errors, refer to the Sentry documentation on capturing errors.

Message Logging

Log informational messages, warnings, or custom events to Sentry.
// Info message
trackMessage('User completed onboarding', 'info')

// Warning
trackMessage('API rate limit approaching', 'warning')

// Error (non-exception)
trackMessage('Failed to load data', 'error', {
  tags: { endpoint: '/api/data' },
})
Record a trail of events leading up to an error, providing valuable context.
import { addBreadcrumb } from '@/utils/analytics'
import { BreadcrumbCategories } from '@/types/errorTracking'

// Navigation breadcrumb
addBreadcrumb({
  category: BreadcrumbCategories.NAVIGATION,
  message: 'Navigated to Settings',
  type: 'navigation',
})

// API call breadcrumb
addBreadcrumb({
  category: BreadcrumbCategories.API,
  message: 'API call to /users',
  type: 'http',
  data: {
    url: '/users',
    method: 'GET',
    status_code: 200,
  },
})

// User action breadcrumb
addBreadcrumb({
  category: BreadcrumbCategories.USER_ACTION,
  message: 'User clicked subscribe button',
  type: 'user',
})
Learn more about breadcrumbs in the Sentry Breadcrumbs documentation.

User Context

Associate errors with specific users to understand who is affected.
// Set user context for errors
setUserContext({
  id: 'user-123',
  email: 'user@example.com',
  username: 'johndoe',
})

// Clear user context (e.g., on logout)
clearUserContext()
For more on user context, see the Sentry User Context documentation.

Tags and Extra Context

Add custom tags and arbitrary data to error reports for better filtering and debugging.
// Set tags (for filtering in Sentry UI)
setTags({
  environment: 'production',
  version: '1.2.3',
  platform: 'ios',
  locale: 'en-US',
})

// Set extra context (additional data)
setExtras({
  user_preferences: { theme: 'dark', notifications: true },
  device_info: { model: 'iPhone 14', os: 'iOS 17' },
  app_state: { screen: 'Home', tab: 'Feed' },
})
Refer to the Sentry Tags and Extra Data documentation for more information.

Performance Monitoring

Sentry can also help monitor your applicationโ€™s performance.
import { sentry } from '@/services/sentry'
// Start a transaction to measure an operation
const transaction = sentry.startTransaction?.({
  name: 'load_products_transaction',
  op: 'http', // Operation type
  description: 'Loading products from API',
})

try {
  // Your code that performs the operation
  const products = await fetchProducts() // Assume fetchProducts is an async function
  
  transaction?.setStatus?.('ok') // Mark transaction as successful
} catch (error) {
  transaction?.setStatus?.('error') // Mark transaction as failed
  trackError(error as Error, { tags: { transaction: 'load_products' } }); // Track the error
  throw error; // Re-throw the error if necessary
} finally {
  transaction?.finish?.(); // End the transaction
}
For comprehensive details on performance monitoring, visit the Sentry Performance Monitoring documentation.

Testing Your Integration

Mock Mode Testing

  1. Ensure your EXPO_PUBLIC_SENTRY_DSN is not set in your apps/app/.env file.
  2. Run your app (yarn ios or yarn android).
  3. Trigger a test error (e.g., throw new Error("Test error from mock mode");).
  4. Check your console logs for messages like ๐Ÿ› [MockSentry] Exception: Error message, indicating that mock errors are being captured.

Testing with Real Services

  1. Add your EXPO_PUBLIC_SENTRY_DSN to apps/app/.env.
  2. Run your app.
  3. Trigger a test error:
    throw new Error('This is a test error from Sentry integration!');
    
  4. Log in to your Sentry dashboard and navigate to Issues to see the captured error. You should also see any associated breadcrumbs, user context, and tags.

Troubleshooting

Errors not showing in Sentry

Problem: Errors are captured in your app but not appearing in the Sentry dashboard. Solution:
  • Double-check that your EXPO_PUBLIC_SENTRY_DSN is correct in apps/app/.env.
  • Verify your device has network connectivity.
  • Ensure your Sentry project is active and correctly configured.
  • Check if the error is being filtered by any beforeSend callbacks in your Sentry configuration.
  • Review your Sentry projectโ€™s quota usage.
  • Check your browserโ€™s developer console or device logs for any errors related to Sentry.

Mock mode in production

Problem: Your app is using mock Sentry services in production. Solution:
  • Verify that your apps/app/.env file exists and is correctly configured with EXPO_PUBLIC_SENTRY_DSN.
  • Ensure your environment variables are prefixed with EXPO_PUBLIC_.
  • Restart your Metro bundler with yarn app:start --clear to ensure environment variables are reloaded.
  • Review your build configuration to ensure .env variables are correctly bundled.