Skip to content

Overview ​

A breadcrumb is a small, timestamped record of something that happened before an error — a console call, an outgoing request, a step in your own code. The SDK keeps a rolling trail of them and attaches it to the next captured exception, so you see the sequence of events that led up to the failure, not just the failure itself.

Breadcrumbs only travel with exceptions. Logs, traces and spans don't carry a trail.

Adding breadcrumbs manually ​

ts
import { addBreadcrumb, captureException } from '@buglapse/node'

addBreadcrumb({
    type: 'payment',
    level: 'info',
    message: 'Charging card',
    data: { orderId: order.id, amount: order.total },
})

try {
    await chargeCard(order)
} catch (error) {
    captureException(error) // ships with the breadcrumb above in its trail
}

Only message is required:

  • type — a free-form string that picks the icon/renderer on the dashboard. Defaults to "debug".
  • level — log | info | warn | error | debug | success. Defaults to "debug"; sets the marker's color.
  • data — optional structured detail, shown on the dashboard as raw JSON.
  • timestamp — set automatically.

One trail per request ​

On a server, a single shared trail would mix breadcrumbs from every concurrent request. Instead, each async context keeps its own:

  • Every scope started from the top level — a request handled by HttpServerIntegration, a withScope() or asyncSpan() around a job — starts with an empty trail. Its breadcrumbs never show up on another request's error.
  • Scopes and spans nested inside it share its trail, so one request accumulates a single trail however deeply your code nests withScope()/span() calls.
  • Breadcrumbs added outside any scope (at startup, in a top-level timer) go into the process-wide root trail. They're attached to errors captured outside a scope, but not to errors inside a request.

Without HttpServerIntegration or your own withScope() per unit of work, all requests share the root trail — the breadcrumbs on an error may then come from a different request.

Automatic breadcrumbs ​

BreadcrumbsIntegration records a breadcrumb for every console.* call and every outgoing HTTP request (fetch(), node:http, node:https and the libraries built on them), with no code changes:

ts
import { use } from '@buglapse/node'
import { breadcrumbsIntegration } from '@buglapse/node/integrations'

use(breadcrumbsIntegration())

Manual and automatic breadcrumbs land in the same trail, in the order they happened.

Trail limit ​

A trail keeps the 50 most recent breadcrumbs; once full, the oldest is dropped as a new one is added.

Viewing breadcrumbs on the dashboard ​

An exception's detail page shows its trail above the stack trace, oldest first. The marker is colored by level; type picks how the row is rendered:

  • console — "Console {level}", with the call's arguments (data.args) as the subtitle.
  • http — method and URL, with the response status next to the title (red for error level). Other keys left in data are shown as raw JSON.
  • anything else — the capitalized type as the title and message as the subtitle, with data as raw JSON.