Bugsnag Error Tracking: Getting Started and Integration Testing Guide

Bugsnag Error Tracking: Getting Started and Integration Testing Guide

Production applications generate errors constantly. Most of them are noise — bots hitting 404s, occasional network timeouts, browser extensions injecting malformed scripts. A small subset are real bugs that affect real users and need to be fixed. The challenge is separating signal from noise efficiently.

Bugsnag was designed to solve this problem. Its error grouping algorithm, stability scoring, and release tracking give you a clear picture of which errors are affecting users, how many users are affected, and whether a new deployment made things better or worse.

This guide covers Bugsnag's architecture, SDK setup across different platforms, and how to integrate error tracking into your testing and release process.

How Bugsnag Organizes Errors

The fundamental unit in Bugsnag is the error event — a single occurrence of an exception or error condition in your application. Events are automatically grouped into issues based on stack trace fingerprinting. All occurrences of the same underlying error appear in a single issue, giving you an accurate count of how often a bug occurs rather than requiring you to manually deduplicate.

Grouping is configurable. If Bugsnag's default grouping creates unwanted splits or merges, you can provide a custom fingerprint:

Bugsnag.addOnError(function(event) {
  // Group all database connection errors together
  if (event.errors[0].errorMessage.includes('ECONNREFUSED')) {
    event.groupingHash = 'database-connection-refused';
  }
});

The stability score is Bugsnag's key metric. It shows the percentage of sessions that are error-free. A stability score of 99.8% means 0.2% of sessions contain at least one unhandled error. This single number tells you more about your application's health than raw error counts, because it accounts for traffic volume and normalizes for usage patterns.

SDK Installation

Bugsnag provides SDKs for virtually every platform — JavaScript, Node.js, React, React Native, iOS, Android, Python, Ruby, Go, Java, and more.

JavaScript/Browser:

<!-- Script tag -->
<script src="//d2wy8f7a9ursnm.cloudfront.net/v7/bugsnag.min.js"></script>
<script>
  Bugsnag.start({ apiKey: 'YOUR_API_KEY' });
</script>
// npm
import Bugsnag from '@bugsnag/js';

Bugsnag.start({
  apiKey: 'YOUR_API_KEY',
  appVersion: '1.4.2',
  releaseStage: 'production',
  enabledReleaseStages: ['production', 'staging'],
  onError: function(event) {
    // Modify or discard events before they're sent
    event.addMetadata('account', {
      id: getCurrentUser().id,
      plan: getCurrentUser().plan,
    });
  },
});

Node.js:

const Bugsnag = require('@bugsnag/js');
const BugsnagPluginExpress = require('@bugsnag/plugin-express');

Bugsnag.start({
  apiKey: 'YOUR_API_KEY',
  plugins: [BugsnagPluginExpress],
  appVersion: process.env.APP_VERSION,
  releaseStage: process.env.NODE_ENV,
});

// Express middleware
const middleware = Bugsnag.getPlugin('express');
app.use(middleware.requestHandler);
// ... routes ...
app.use(middleware.errorHandler);

Python:

import bugsnag
from bugsnag.wsgi.middleware import BugsnagMiddleware

bugsnag.configure(
    api_key="YOUR_API_KEY",
    project_root="/app",
    app_version="1.4.2",
    release_stage="production",
    notify_release_stages=["production", "staging"],
)

# Django integration
MIDDLEWARE = ['bugsnag.django.middleware.BugsnagMiddleware'] + MIDDLEWARE

Identifying Users

Attaching user information to error events is essential for understanding impact and for filtering in the dashboard:

Bugsnag.setUser('user-123', 'user@example.com', 'Jane Smith');
bugsnag.configure_request(
    user={"id": "user-123", "email": "user@example.com", "name": "Jane Smith"}
)

With user information attached, each error shows exactly how many distinct users are affected — a critical distinction between a bug affecting one user repeatedly and a bug affecting thousands of users once each.

Custom Metadata and Breadcrumbs

Context is everything in debugging. Bugsnag lets you attach custom metadata to errors:

// Attach account-level context
Bugsnag.addMetadata('account', {
  id: '123',
  plan: 'enterprise',
  billing_status: 'active',
});

// Attach feature-specific context
Bugsnag.addMetadata('checkout', {
  cart_items: 3,
  total_value: 149.99,
  payment_method: 'credit_card',
  coupon_code: 'SUMMER20',
});

Breadcrumbs are an automatic trail of recent events leading up to an error:

// Leave a breadcrumb manually
Bugsnag.leaveBreadcrumb('User clicked checkout', {
  cart_items: 3,
  total: 149.99,
}, 'user');

Bugsnag also automatically captures breadcrumbs for navigation events, network requests, and console output. When you view an error, you see the last 25 breadcrumbs — the sequence of events leading to the crash.

Release Tracking

Release tracking is where Bugsnag connects error monitoring to your deployment process. By reporting builds to Bugsnag when you deploy, you get:

  • New vs. existing errors: Are errors appearing for the first time in this release, or were they present before?
  • Regression detection: Did a bug that was fixed reappear in this release?
  • Stability comparison: Is the new release more or less stable than the previous one?

Report a build via the Bugsnag Build API:

curl --http1.1 \
  https://build.bugsnag.com/ \
  --header "Content-Type: application/json" \
  --data '{
    "apiKey": "YOUR_API_KEY",
    "appVersion": "1.4.2",
    "releaseStage": "production",
    "builderName": "deploy-bot",
    "sourceControl": {
      "provider": "github",
      "repository": "https://github.com/yourorg/yourapp",
      "revision": "'"$GIT_SHA"'"
    }
  }'

For CI/CD integration, this call typically goes in your deployment pipeline after the deploy completes:

# GitHub Actions example
- name: Notify Bugsnag of deployment
  run: |
    curl --http1.1 \
      https://build.bugsnag.com/ \
      --header "Content-Type: application/json" \
      --data "{
        \"apiKey\": \"${{ secrets.BUGSNAG_API_KEY }}\",
        \"appVersion\": \"${{ github.ref_name }}\",
        \"releaseStage\": \"production\",
        \"sourceControl\": {
          \"provider\": \"github\",
          \"repository\": \"${{ github.server_url }}/${{ github.repository }}\",
          \"revision\": \"${{ github.sha }}\"
        }
      }"

Integration Testing with Bugsnag

Testing your Bugsnag integration requires verifying both that events are sent correctly and that they're not sent when they shouldn't be.

Test error reporting works:

// In a test environment, verify the notifier is configured
describe('Bugsnag integration', () => {
  it('reports errors to Bugsnag', () => {
    const spy = jest.spyOn(Bugsnag, 'notify');
    
    // Trigger an error condition
    triggerErrorCondition();
    
    expect(spy).toHaveBeenCalledWith(
      expect.objectContaining({
        message: 'Expected error message',
      })
    );
  });
  
  it('attaches user context to errors', () => {
    const spy = jest.spyOn(Bugsnag, 'notify');
    setCurrentUser({ id: 'user-123' });
    
    triggerErrorCondition();
    
    expect(spy).toHaveBeenCalled();
    // Verify user metadata would be attached via onError callback
  });
});

Verify errors are not reported in development:

Bugsnag.start({
  apiKey: 'YOUR_API_KEY',
  releaseStage: process.env.NODE_ENV,
  enabledReleaseStages: ['production', 'staging'], // development excluded
});

// In tests for development environment:
it('does not report errors in development', () => {
  process.env.NODE_ENV = 'development';
  const notifySpy = jest.spyOn(Bugsnag, 'notify');
  
  triggerError();
  
  // Bugsnag won't actually send in development, but calling notify is fine
  // What matters is that errors aren't polluting production dashboards
});

Test source map upload (critical for production debugging):

// webpack plugin configuration
const BugsnagSourceMapUploaderPlugin = require('bugsnag-source-map-uploader-webpack-plugin');

module.exports = {
  plugins: [
    new BugsnagSourceMapUploaderPlugin({
      apiKey: process.env.BUGSNAG_API_KEY,
      appVersion: process.env.APP_VERSION,
      overwrite: true,
    }),
  ],
};

Without source maps uploaded, production stack traces show minified code. Source maps transform them to show your original source files, line numbers, and function names.

Alerting and Workflow Integration

Bugsnag integrates with Slack, PagerDuty, GitHub Issues, Jira, and many other tools. Configure alerts to fire when:

  • A new error occurs (not seen before in any release)
  • Error rate spikes above a threshold
  • Stability score drops below a threshold
  • A specific user or account triggers an error

For on-call workflows, the PagerDuty and OpsGenie integrations let you escalate critical errors directly to your incident management system.

Session Tracking

Bugsnag's session tracking connects the error data to user session context, enabling the stability score calculation:

Bugsnag.start({
  apiKey: 'YOUR_API_KEY',
  autoTrackSessions: true, // default: true
});

// For SPAs, manually start sessions on route change
router.on('navigate', () => {
  Bugsnag.startSession();
});

Stability scores require session tracking to be enabled. Without it, you have error counts but no denominator to calculate what percentage of sessions are affected.

Practical QA Workflow

  1. Enable Bugsnag in staging with a separate API key so staging errors don't pollute production dashboards.
  2. Run your test suite against staging — Bugsnag captures any errors that occur during testing that didn't cause test failures (warnings, non-fatal errors).
  3. Before deployment: Check the staging Bugsnag dashboard for new errors introduced by the branch.
  4. After deployment to production: Monitor the stability score for 15-30 minutes. A healthy deployment shows stable or improving stability; a degraded deployment shows a dip.
  5. Set up release comparisons: Use Bugsnag's release comparison view to verify the new version has fewer or equal errors compared to the previous version.

The combination of pre-deployment error review in staging and post-deployment stability monitoring in production gives you a systematic quality gate at every release.

Read more

Start now free