AI-powered crash analysis is now available on all plans — including Free.Read the crash analysis guide

React Native Network Request Monitoring: A Complete Guide

NFNourin Mahfuj Finick··8 min read

Network errors are a leading cause of crashes and user-facing failures in React Native apps. An API that returns an unexpected response triggers a null reference error. A timeout causes an unhandled rejection. A 401 redirects users to a broken state. Without network monitoring, you see the crash but not the cause.


This guide covers how to monitor every network request in a production React Native app.


What Network Monitoring Captures


A network monitoring setup should capture:

  • Request: URL (sanitized), HTTP method
  • Response: Status code, response time (ms)
  • Errors: Network timeouts, connection failures, DNS errors
  • Correlation: Which session and which crash occurred after this request

It should NOT capture: request/response bodies, authentication headers, or any user data.


Automatic Monitoring with BugsPulse


BugsPulse patches the global fetch API when captureNetworkRequests: true is set:


BugsPulse.init({
  apiKey: 'bp_your_key',
  captureNetworkRequests: true,
  // Sanitize URLs — remove user IDs and tokens from paths
  networkUrlSanitizer: (url) => {
    return url
      .replace(//users/[^/?]+/, '/users/[id]')
      .replace(//orders/[^/?]+/, '/orders/[id]')
      .replace(/[?&]token=[^&]+/, '');
  },
});

Every fetch() call in your app — including calls made by third-party libraries that use fetch internally — is captured automatically with URL, method, status, and duration.


Axios Interceptor


If you use Axios, add the BugsPulse interceptor to your Axios instance:


import axios from 'axios';
import BugsPulse from '@bugspulse/react-native';

const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
});

// Response interceptor — captures all responses and errors
apiClient.interceptors.response.use(
  (response) => {
    BugsPulse.captureNetworkRequest({
      url: response.config.url!,
      method: response.config.method!.toUpperCase(),
      statusCode: response.status,
      duration: Date.now() - (response.config as any)._startTime,
    });
    return response;
  },
  (error) => {
    BugsPulse.captureNetworkRequest({
      url: error.config?.url ?? 'unknown',
      method: error.config?.method?.toUpperCase() ?? 'UNKNOWN',
      statusCode: error.response?.status ?? 0,
      errorMessage: error.message,
    });
    return Promise.reject(error);
  }
);

// Request interceptor — record start time
apiClient.interceptors.request.use((config) => {
  (config as any)._startTime = Date.now();
  return config;
});

Monitoring WebSocket Connections


For real-time apps using WebSockets:


class MonitoredWebSocket {
  private ws: WebSocket;
  private url: string;

  constructor(url: string) {
    this.url = url;
    this.ws = new WebSocket(url);

    this.ws.addEventListener('open', () => {
      BugsPulse.addBreadcrumb({
        category: 'websocket',
        message: `WebSocket connected: ${this.sanitizeUrl(url)}`,
        level: 'info',
      });
    });

    this.ws.addEventListener('error', (event) => {
      BugsPulse.addBreadcrumb({
        category: 'websocket',
        message: `WebSocket error: ${this.sanitizeUrl(url)}`,
        level: 'error',
      });
    });

    this.ws.addEventListener('close', (event) => {
      if (event.code !== 1000) { // 1000 = normal closure
        BugsPulse.addBreadcrumb({
          category: 'websocket',
          message: `WebSocket closed unexpectedly: code ${event.code}`,
          level: 'warning',
        });
      }
    });
  }

  private sanitizeUrl(url: string): string {
    return url.replace(/[?&]token=[^&]+/, '').replace(//users/[^/]+/, '/users/[id]');
  }
}

Debugging Slow APIs


Network monitoring captures request duration, which lets you identify slow endpoints that degrade user experience before they cause crashes:


In your BugsPulse dashboard, filter sessions by network events with duration > 3000ms. You'll see which API endpoints are consistently slow and which users are most affected.


You can also set up local alerts:


// Alert on slow requests in your app logic
async function fetchWithMonitoring(url: string, options?: RequestInit) {
  const start = Date.now();
  try {
    const response = await fetch(url, options);
    const duration = Date.now() - start;

    if (duration > 5000) {
      BugsPulse.addBreadcrumb({
        message: `Slow API: ${url} took ${duration}ms`,
        level: 'warning',
        data: { url: sanitizeUrl(url), duration, status: response.status },
      });
    }

    return response;
  } catch (error) {
    BugsPulse.captureException(error as Error, {
      context: { url: sanitizeUrl(url), duration: Date.now() - start },
    });
    throw error;
  }
}

Correlating Network Failures with Crashes


The most valuable use of network monitoring is correlation: seeing the API call that happened right before a crash.


In BugsPulse, open any crash session and look at the timeline. A typical crash story looks like:


14:23:01  Navigation → CheckoutScreen
14:23:02  TAP → PlaceOrderButton
14:23:02  → POST /api/orders (pending)
14:23:03  ← POST /api/orders  STATUS 500  (1024ms)
14:23:03  CRASH: TypeError: Cannot read property 'orderId' of null

From this, the bug is obvious: the 500 response returned a body without orderId, and the error handling code assumed it would always be present. You can fix it in 5 minutes — without ever needing to reproduce the crash locally.


What Not to Capture


Network monitoring must not capture:


BugsPulse.init({
  captureNetworkRequests: true,
  // Always false — bodies may contain PII
  captureNetworkRequestBodies: false,
  captureNetworkResponseBodies: false,
  // Always false — headers contain auth tokens
  captureNetworkHeaders: false,
});

The URL, method, status code, and duration are sufficient to debug 95% of network-related crashes. Bodies and headers contain user data that creates GDPR and security risk.


Summary


React Native network monitoring requires patching fetch (automatic with BugsPulse) and optionally adding Axios interceptors. Capture URL (sanitized), method, status, and duration — never bodies or headers. The resulting network timeline in crash reports turns mysterious failures into root causes you can fix in minutes.