Skip to Content
v1.33.8 · shipped One-screen report · Looks like your app Read the changelog →
SDK reference@mushi-mushi/node

@mushi-mushi/node

The Mushi Mushi server-side SDK for Node.js apps. It forwards unhandled exceptions, adds HTTP error handlers for Express, Fastify and Hono, and tags each handler report with the request method, URL and trace context (W3C traceparent and sentry-trace headers, when present). To attach a user, pass userId to captureReport().

Install

pnpm add @mushi-mushi/node

Create a client

Every handler below takes the same client:

import { MushiNodeClient } from '@mushi-mushi/node' export const client = new MushiNodeClient({ apiKey: process.env.MUSHI_API_KEY!, projectId: process.env.MUSHI_PROJECT_ID!, environment: process.env.NODE_ENV, // optional release: process.env.GIT_SHA, // optional })

Express

import express from 'express' import { mushiExpressErrorHandler } from '@mushi-mushi/node/express' const app = express() // …all your routes… app.use(mushiExpressErrorHandler({ client })) // mount LAST so it sees every other route

Fastify

import Fastify from 'fastify' import { mushiFastifyPlugin } from '@mushi-mushi/node/fastify' const app = Fastify() mushiFastifyPlugin(app, { client })

Hono

Hono’s onError must return a Response, so pass your own handler as the second argument. Mushi Mushi reports the error, then calls it.

import { Hono } from 'hono' import { mushiHonoErrorHandler } from '@mushi-mushi/node/hono' const app = new Hono() app.onError(mushiHonoErrorHandler({ client }, () => new Response('Server error', { status: 500 })))

Process-level fallbacks

Attach uncaughtException + unhandledRejection hooks so nothing escapes:

import { attachUnhandledHook } from '@mushi-mushi/node' attachUnhandledHook({ client })

Programmatic submit

Use the client directly when you want to report outside the request cycle (cron jobs, queue workers, integration failures):

import { MushiNodeClient } from '@mushi-mushi/node' const mushi = new MushiNodeClient({ apiKey: process.env.MUSHI_API_KEY!, projectId: process.env.MUSHI_PROJECT_ID!, environment: 'production', release: process.env.GIT_SHA, }) await mushi.captureReport({ description: 'Refund webhook returned 500', severity: 'high', component: 'billing', metadata: { invoiceId, attempt }, })

The Node SDK sends to the same API as the web SDK, so server-thrown bugs and user-side bugs land in the same queue.

PII and credential scrubbing

Every description, url, and error.message value is passed through the core PII scrubber before it leaves the process:

  • JWT-shaped tokens (three dot-separated eyJ… segments, regardless of header scheme) are redacted to [REDACTED_JWT].
  • Emails, phone numbers and similar patterns are replaced with [REDACTED_EMAIL], [REDACTED_PHONE], and friends.
  • Sensitive query-string keys (token, api_key, password, secret, …) have their values replaced with [Scrubbed].

This applies to captureReport, mushiExpressErrorHandler, and mushiTraceMiddleware, with no extra configuration.

If you use Authorization: Token <jwt> (Conduit / RealWorld spec), the JWT in that header is never captured: the SDK only reads response status codes and timing from network spans, not request headers.

The following fields are scrubbed before the report leaves the Node process:

FieldScrubber applied
descriptionPII scrub (emails, phones, JWTs, SSNs, CC-shaped strings)
environment.urlURL scrub (sensitive query-param keys and value patterns)
error.messagePII scrub
error.stackPII scrub
request.url (trace middleware)URL scrub

userId and host-supplied metadata are left unmodified. The SDK cannot know which IDs or metadata keys are safe to alter, so the host is responsible for any additional scrubbing at those sites.

Last updated on