Node.js integration: automatic reporting of uncaughtException and unhandledRejection, plus optional request middleware. Uses @telemetry-tracker/core under the hood; all payloads include anonymous id and SDK version (see telemetry-core).
In a monorepo workspace:
pnpm add @telemetry-tracker/nodeRequires @telemetry-tracker/core ^1.5.0 (provides ingestError for fatal flushes).
Call init(config) once at process startup (e.g. before starting your HTTP server). This will:
- Initialize the core SDK.
- Register
process.on("uncaughtException")andprocess.on("unhandledRejection")to report those errors, flush ingest (up to 2s), then exit.
import { init, trackEvent, trackError } from "@telemetry-tracker/node";
init({
ingestUrl: "https://your-api.example.com",
app: "my-backend",
apiKey: process.env.TELEMETRY_API_KEY,
platform: "node", // default
// exitOnUnhandledRejection: true, // default — report, flush, exit(1)
});| Export | Description |
|---|---|
init(config) |
Initialize SDK and install global error handlers. |
identify(userId) |
Set current user id (e.g. from request context). |
trackEvent(name, properties?) |
Send a named event. |
trackError(error, context?) |
Report an error. |
getConfig() |
Current config or null. |
middleware(opts?) |
Optional generic middleware that tracks $request events (method, url, duration). |
Config extends telemetry-core and requires app; platform defaults to "node".
| Option | Default | Description |
|---|---|---|
exitOnUnhandledRejection |
true |
After reporting an unhandled rejection, flush and process.exit(1) (Node’s default since v15). Set false to only report and keep running. |
fatalFlushTimeoutMs |
2000 |
Max wait for fatal ingest before exit. Cleared when ingest settles (does not keep the process alive). |
After init():
- uncaughtException: Error is reported with
{ source: "uncaughtException" }, ingest is flushed (≤fatalFlushTimeoutMs, default 2s), then the process exits with code 1. Non-Error throws (null, strings, objects, …) are normalized first. - unhandledRejection: Reason is reported with
{ source: "unhandledRejection" }. By default the process then flushes and exits with code 1 (same as Node without the SDK). SetexitOnUnhandledRejection: falseto keep the legacy “report only” behaviour.
With node --unhandled-rejections=strict, rejections are also raised as uncaught exceptions; the SDK still reports once and exits 1 (in-flight ingest is awaited if you already called trackError(err) before rethrowing).
You can still use trackError in try/catch for extra context.
middleware(opts?) returns a generic middleware function with signature:
(req, res, next) => voidduration_ms is measured from middleware entry until the response emits finish or close (not the request body end). next() is called exactly once.
Options:
trackRequestBody(defaultfalse): when true, includesreq.bodyin the$requestevent properties (use carefully — may contain PII).
import { init, middleware } from "@telemetry-tracker/node";
init({ ingestUrl: "...", app: "api" });
const telemetryMiddleware = middleware({ trackRequestBody: false });
// Express
app.use(telemetryMiddleware);For Express you’d typically do app.use(telemetryMiddleware) if the middleware calls next() and matches Express’ (req, res, next) shape. Our middleware is generic and may need a thin wrapper to match your framework’s expectations. For NestJS, see sdk-nestjs.md.