Files
WRNexusJS/packages/tracking
2026-07-27 12:42:18 +05:30
..
2026-07-27 12:42:18 +05:30
2026-07-27 12:42:18 +05:30
2026-07-27 12:42:18 +05:30
2026-07-12 15:55:18 +05:30

@wrnexus/tracking

Error tracking for WrNexus apps: capture exceptions manually or via middleware and fan them out to pluggable sinks.

Part of the WrNexus framework — an SSR-first, Bun-native full-stack web framework.

Overview

@wrnexus/tracking is a small, server-side error-capture layer. You create a tracker with one or more sinks, then feed it errors — either manually with tracker.capture(err, context) or automatically by mounting tracker.middleware() in your request pipeline. A consoleSink is included; forwarding to Sentry, Datadog, or any other backend is just a matter of writing a tiny sink. Reach for it when you want a single, sink-agnostic place to route application errors. Sinks run best-effort — a throwing sink never breaks the request.

Installation

bun add @wrnexus/tracking

Private package — the machine must be authenticated to the wrnexus npm org (a read token in ~/.npmrc). Requires Bun (Node is not supported).

API

createTracker(options?): Tracker

Creates a tracker. TrackerOptions:

Option Type Description
sinks ErrorSink[] Initial sinks to fan events out to. Defaults to [].
now () => number Clock used for event.timestamp (epoch ms). Defaults to Date.now.
beforeSend (event: ErrorEvent) => ErrorEvent | null Scrub/enrich an event before it reaches any sink. Return null to drop it.

The returned Tracker:

Member Signature Description
capture (error: unknown, context?: Record<string, unknown>) => Promise<void> Normalizes any thrown value into an Error, builds an ErrorEvent, runs beforeSend, then dispatches to all sinks. Non-Error values are wrapped in an Error named NonError.
addSink (sink: ErrorSink) => void Registers an additional sink at runtime.
middleware () => Middleware Returns a WrNexus Middleware that captures any error thrown downstream, then re-throws it so the framework's error handler still produces the response.

The middleware attaches this context to captured events:

{ method: ctx.req.method, path: ctx.url.pathname, requestId: ctx.locals.requestId }

consoleSink: ErrorSink

A built-in sink that logs a compact one-line message via console.error, e.g. [error] TypeError: cannot read x {"userId":42}.

Types

interface ErrorEvent {
  error: Error;
  context: Record<string, unknown>; // request info, user id, tags…
  timestamp: number; // epoch ms
}

interface ErrorSink {
  name?: string;
  capture(event: ErrorEvent): void | Promise<void>;
}

Usage

Manual capture:

import { createTracker, consoleSink } from "@wrnexus/tracking";

const tracker = createTracker({ sinks: [consoleSink] });

try {
  await doWork();
} catch (err) {
  await tracker.capture(err, { userId: 42, op: "doWork" });
  throw err;
}

As request middleware:

import { createTracker, consoleSink } from "@wrnexus/tracking";

const tracker = createTracker({ sinks: [consoleSink] });

app.use(tracker.middleware()); // captures + re-throws downstream errors

A custom sink with beforeSend scrubbing:

import { createTracker, type ErrorSink } from "@wrnexus/tracking";

const sentrySink: ErrorSink = {
  name: "sentry",
  async capture(event) {
    await Sentry.captureException(event.error, { extra: event.context });
  },
};

const tracker = createTracker({
  sinks: [sentrySink],
  beforeSend(event) {
    delete event.context.password; // scrub secrets
    return event; // return null to drop the event entirely
  },
});

tracker.addSink(anotherSink); // add more sinks later

Requirements / Notes

  • Runs on Bun only (Node is not supported).
  • Peer package: @wrnexus/core — the Context and Middleware types used by tracker.middleware() come from there.
  • Sink dispatch is fire-and-forget-safe: all sinks run via Promise.all, and a sink that throws is swallowed so it can never break the app.