Skip to content

Node.js SDK

The Pionne SDK for Node.js. Auto-captures uncaughtException and unhandledRejection, enriches every event with runtime context (Node version, OS, hostname, PID, memory).

Current version: 0.3.6

Terminal window
npm install @pionne/node
index.ts
import { Pionne } from '@pionne/node';
Pionne.init({
token: 'pio_live_…',
release: '1.0.0',
environment: 'production',
});
  • process.on('uncaughtException') — uncaught sync exceptions
  • process.on('unhandledRejection') — promises rejected without .catch()
  • process.version — Node version
  • os.platform(), os.release() — OS and release
  • os.hostname() — machine name
  • process.pid — PID
  • process.memoryUsage() — RSS, heap used, heap total
  • console.log / console.warn / console.error
  • Outbound HTTP requests via http/https (instrumentation of request)
Pionne.init(options);
Pionne.captureException(error, { tags, contexts });
Pionne.captureMessage('Cache miss', { level: 'info' });
Pionne.setUser({ id: 'user_42' });
Pionne.setTags({ region: 'eu-west-1' });
Pionne.setEnabled(false);
Pionne.addBreadcrumb({ category: 'db', message: 'SELECT * FROM users' });
import express from 'express';
import { Pionne } from '@pionne/node';
Pionne.init({ token: 'pio_live_…' });
const app = express();
// ... your routes ...
// The error middleware MUST be registered last
app.use(Pionne.expressErrorHandler());
app.listen(3000);

For BullMQ, Bee-Queue, Agenda, Worker Threads or any job runner, wrap each handler in try/catch:

worker.on('failed', (job, err) => {
Pionne.captureException(err, {
tags: { job: job.name },
contexts: { job: { id: job.id, data: job.data } },
});
});

On a Node backend, the IP used for the lookup is the server’s, not the end client’s. Useful to spot a crash localised to one cloud region (e.g. eu-west-3 vs us-east-1) without touching infra logs.

Pionne.init({
token: 'pio_live_…',
sendGeography: true, // ← opt-in
});

At boot, a single HTTP call to https://ipapi.co/json/ (4 s timeout) attaches contexts.geo = { city, region, country, country_code } to every subsequent event. If the lookup fails (egress firewall, rate-limit), the SDK silently keeps shipping events without geo.

Running an auto-scaled cluster? Set the pod region directly in tags (tags: { region: process.env.AWS_REGION }) — more reliable than an IP lookup from inside the SDK.

Bundle ID pinning is mobile only (iOS/Android/RN/Flutter) — it protects against APK/IPA decompilation. On Node, your token lives server-side (.env, secrets manager, EAS env vars…) and is never shipped to a client: the threat doesn’t exist.

The “Bundle ID” field is hidden in the mobile dashboard for Node projects — filling it manually would 403 every event (the SDK does not send app_id). To differentiate deployments, use tags:

Pionne.init({
token: process.env.PIONNE_TOKEN,
tags: { deployment: process.env.APP_DEPLOYMENT ?? 'prod', region: process.env.AWS_REGION },
});

More details: Bundle ID Pinning → Backends without bundle_id.