Skip to content

Buglapse's Node SDK captures errors, logs, traces and span metrics from a Node.js process — an API server, a queue worker, a cron script. Your project is identified by its DSN (https://{key}@{host}) — find it on the project's Settings → General tab.

Install ​

Until the SDK is published to the public npm registry, @buglapse/* packages are served by Buglapse itself. Point the scope at it once, in an .npmrc next to your package.json:

ini
@buglapse:registry=https://app.buglapse.com/npm/

Then install as usual — npm update picks up new versions like any other dependency:

bash
npm install @buglapse/node

Requires Node 18.19 or newer. The package ships both ESM and CommonJS builds, so import and require() both work.

Initialize ​

Call init() as early as possible — at the top of your entry file, before the rest of your app is imported and before the server starts listening:

ts
import { init } from '@buglapse/node'

init({
    dsn: process.env.BUGLAPSE_DSN,
    environment: process.env.NODE_ENV,
    release: process.env.GIT_SHA,
})

Everything is exported as named functions from @buglapse/node (captureException, log, asyncSpan, ...); the built-in integrations live in a separate entry, @buglapse/node/integrations.

On its own, init() only captures crashes (see below). For a typical API server, turn on per-request isolation and tracing, runtime context and breadcrumbs:

ts
import { init } from '@buglapse/node'
import {
    breadcrumbsIntegration,
    httpErrorsIntegration,
    httpServerIntegration,
    httpTracingIntegration,
    nodeContextIntegration,
} from '@buglapse/node/integrations'

init({
    dsn: process.env.BUGLAPSE_DSN,
    environment: process.env.NODE_ENV,
    integrations: [
        httpServerIntegration(),   // own scope, breadcrumbs and trace per incoming request
        httpTracingIntegration(),  // outgoing requests as child spans
        httpErrorsIntegration(),   // failed outgoing requests as error logs
        breadcrumbsIntegration(),  // console calls and outgoing requests as breadcrumbs
        nodeContextIntegration(),  // Node version, OS and host name on every event
    ],
})

Each one is described on its own page under Integrations.

What you get out of the box ​

Right after init(), UncaughtExceptionIntegration is listening for the process's uncaughtException and unhandledRejection events: a crash is reported, the buffered events are flushed, and the process exits with code 1, as Node would do on its own. Nothing else is enabled by default.

Errors your framework catches itself — a throw inside an Express or Fastify route handler — never become uncaught, so they need one line in the framework's error handler. See Capturing Errors.

Your first manual event ​

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

addBreadcrumb({ type: 'job', level: 'info', message: 'Started invoice export' })

try {
    await exportInvoices()
} catch (error) {
    captureException(error)
}

log.info('Invoice export finished', { count: 42 })

Open the project's Exceptions page and it should show up within a few seconds; the log lands on Logs.

Before you deploy ​

  • Allowed domains. Node doesn't send an Origin header. If the project has a list under Settings → Security → Allowed domains, every request from a server is rejected with 403. Keep that list empty for server projects — or use a separate Buglapse project for the server and one for the browser.
  • Short-lived processes. Events are batched and sent in the background. A script, a CLI command or a serverless function that ends with process.exit() or gets frozen by its platform must await flush() first — see Transports.
  • The DSN. It's safe to keep in an environment variable or a secret store; it only allows sending events, not reading them.