All integrations

Express / Connect

Any Node web server - page yourself the moment a 5xx leaks.

LiveSDKenv var

One-line Express/Connect error middleware. Goes after all your routes, catches 5xx responses + thrown errors, and fires a Chirp notification with the route, status code, and the first stack frame. Never blocks a request: the Chirp transport is fire-and-forget so a Chirp outage cannot worsen an incident.

Use this when you want fast pager-style alerts for production errors without standing up Sentry / Datadog. Pair with the rate limiter (`rateLimit: "5/min"`) to avoid getting buried under cascading-failure spam - Chirp deduplicates identical (route, status, error.message) tuples within the window.

Prerequisites

  • Node 18+ with Express 4+ or Connect.
  • A Chirp API key set in the environment.

Setup

  1. 1

    Install the SDK

    Single dep. The Express middleware lives at chirp/express.

    shell
    npm install chirp
  2. 2

    Set CHIRP_API_KEY in production env

    However your platform handles env vars: Railway/Render/Heroku config var, Kubernetes secret, .env file (don't commit). The middleware reads process.env.CHIRP_API_KEY on startup and caches it.

  3. 3

    Mount the middleware after your routes

    Order matters: Express error middleware must come AFTER all routes and the request body parser. Mount it last.

    server.ts
    import express from 'express';
    import { chirpErrorNotifier } from 'chirp/express';
    
    const app = express();
    
    // Body parser, routes, etc.
    app.use(express.json());
    app.use('/api', apiRoutes);
    
    // Error notifier - last middleware in the chain.
    app.use(chirpErrorNotifier({
      service:   'api',
      env:       process.env.NODE_ENV ?? 'production',
      rateLimit: '10/min',         // dedupe + rate-limit window
      ignore:    [400, 401, 404],  // don't ping on these (default: [400-499])
    }));
    
    app.listen(3000);
  4. 4

    (Optional) Wrap async handlers explicitly

    Express 4 doesn't auto-catch async errors. Either upgrade to Express 5, or wrap async handlers with chirp/express's asyncHandler so thrown errors hit the notifier instead of crashing the process.

    typescript
    import { asyncHandler } from 'chirp/express';
    
    app.get('/users/:id', asyncHandler(async (req, res) => {
      const user = await db.users.findById(req.params.id);
      res.json(user);
    }));

What you’ll see

Notification: "API · 500" - title is the HTTP method + route (`POST /users`), body is the error class + first line of the stack. Severity-tinted (5xx red, 4xx muted). Tap to deep-link to your error tracker if you've configured `errorTrackerBaseUrl`. Bursts of identical errors collapse into one notification per `rateLimit` window.

Troubleshooting

Errors don't fire pings.
Most common: middleware mounted before routes. Express only routes errors to the *next* error middleware, so it must come AFTER everything. Verify by adding app.get('/boom', () => { throw new Error('test') }) and hitting it.
Async route errors crash the process instead of pinging.
Express 4 doesn't auto-catch async throws. Either wrap with asyncHandler or upgrade to Express 5. Crashing is the default behavior; the notifier never sees the error.
Getting paged for 4xx errors.
Default ignore is [400-499]. If you've overridden ignore, restore the default or be explicit: ignore: [400, 401, 403, 404, 422].