bugstack-sdk
v2.0.2
Published
Framework-agnostic error capture SDK with adapters for Next.js, Express, and more - automatically capture, report, and fix errors
Downloads
430
Maintainers
Readme
bugstack-sdk
Framework-agnostic error capture SDK for Node.js. Automatically captures errors with full context and reports them to BugStack for AI-powered fix generation.
Get your API key at: dashboard.bugstack.ai
Features
- Multiple frameworks — First-class support for Next.js, Express, and generic Node.js
- Full error context — Captures stack traces, request body, headers, query params, route params
- Automatic sanitization — Sensitive data (passwords, tokens, API keys) is redacted automatically
- Non-blocking — Error reporting is async and never slows down your responses
- Deduplication — Same errors are batched within a configurable time window
- Retry queue — Failed reports are retried with exponential backoff
- TypeScript first — Full type safety with comprehensive type definitions
Installation
npm install bugstack-sdkQuick Start
Next.js (App Router)
1. Initialize the client once:
// lib/bugstack.ts
import { ErrorCaptureClient } from "bugstack-sdk";
ErrorCaptureClient.init({
apiKey: process.env.BUGSTACK_API_KEY!,
endpoint: "https://bugstack-error-service.onrender.com/api/capture",
});2. Wrap your API route handlers:
// app/api/users/route.ts
import { NextResponse } from "next/server";
import { withErrorCapture } from "bugstack-sdk/next";
import "@/lib/bugstack"; // ensures client is initialized
export const GET = withErrorCapture(async (request) => {
const users = await db.users.findMany();
return NextResponse.json({ users });
});
export const POST = withErrorCapture(async (request) => {
const body = await request.json();
const user = await db.users.create({ data: body });
return NextResponse.json({ user }, { status: 201 });
});3. Dynamic routes with params:
// app/api/users/[id]/route.ts
import { NextResponse } from "next/server";
import { withErrorCapture } from "bugstack-sdk/next";
import "@/lib/bugstack";
export const GET = withErrorCapture<{ id: string }>(
async (request, { params }) => {
const user = await db.users.findUnique({ where: { id: params.id } });
if (!user) throw new Error("User not found");
return NextResponse.json({ user });
}
);Express
Option A: Error handler middleware (recommended)
import express from "express";
import { bugstackErrorHandler } from "bugstack-sdk/express";
const app = express();
// Your routes
app.get("/api/users", async (req, res) => {
const users = await db.users.findMany();
res.json({ users });
});
// Add BugStack error handler AFTER all routes
app.use(
bugstackErrorHandler({
apiKey: process.env.BUGSTACK_API_KEY!,
endpoint: "https://bugstack-error-service.onrender.com/api/capture",
})
);Option B: Wrap individual route handlers
import { initBugStack, wrapExpressHandler } from "bugstack-sdk/express";
// Initialize once
app.use(
initBugStack({
apiKey: process.env.BUGSTACK_API_KEY!,
endpoint: "https://bugstack-error-service.onrender.com/api/capture",
})
);
// Wrap specific routes
app.get("/api/users/:id", wrapExpressHandler(async (req, res) => {
const user = await getUser(req.params.id);
res.json(user);
}));Generic Node.js
For any Node.js application (scripts, workers, serverless functions, etc.):
import { initBugStack, captureError, installGlobalHandlers } from "bugstack-sdk/generic";
// Initialize once
initBugStack({
apiKey: process.env.BUGSTACK_API_KEY!,
endpoint: "https://bugstack-error-service.onrender.com/api/capture",
});
// Optional: catch uncaught exceptions and unhandled rejections globally
installGlobalHandlers();
// Capture errors manually in try/catch blocks
try {
await processData();
} catch (error) {
await captureError(error, { operation: "processData" });
}Wrap functions for automatic capture:
import { wrapFunction } from "bugstack-sdk/generic";
const processData = wrapFunction(
async (data: Input) => {
// errors thrown here are automatically captured
return transform(data);
},
{ operation: "processData" }
);Create scoped capture functions:
import { createErrorCapture } from "bugstack-sdk/generic";
const captureDbError = createErrorCapture({ component: "database" });
try {
await db.query("SELECT ...");
} catch (error) {
await captureDbError(error, { query: "SELECT ..." });
}Other Languages
BugStack also provides SDKs for:
| Language | Package | Install |
|----------|---------|---------|
| Python | bugstack | pip install bugstack |
| Ruby | bugstack | gem install bugstack |
| Go | bugstack-go | go get github.com/MasonBachmann7/bugstack-go |
Configuration
Full Options
import { ErrorCaptureClient } from "bugstack-sdk";
ErrorCaptureClient.init({
// Required
apiKey: "your-api-key",
// Endpoint (defaults to localhost for local dev)
endpoint: "https://bugstack-error-service.onrender.com/api/capture",
// Optional — defaults shown
projectId: "",
environment: process.env.NODE_ENV, // "development", "production", etc.
enabled: true, // set false to disable capture entirely
// Request capture
captureRequestBody: true,
captureQueryParams: true,
captureHeaders: true,
maxBodySize: 10000, // 10KB max body capture
// Additional fields to redact (added to built-in defaults)
redactFields: ["customSecret", "internalToken"],
// Custom metadata included with every error
metadata: { service: "api", version: "1.0.0" },
// Network
timeout: 5000, // 5s timeout for error reporting
deduplicationWindow: 5 * 60 * 1000, // 5 min window for dedup
// Debug logging (defaults to true in development)
debug: false,
// Custom filter — return false to skip certain errors
shouldCapture: (error, request) => {
if (error.message.includes("not found")) return false;
return true;
},
// Transform errors before sending
beforeSend: (capturedError) => {
capturedError.metadata = { ...capturedError.metadata, custom: "value" };
return capturedError; // return null to skip
},
});Environment Variables
The SDK reads these automatically:
BUGSTACK_API_KEY=your-api-key # Required
BUGSTACK_ENDPOINT=https://bugstack-error-service.onrender.com/api/capture # Optional
BUGSTACK_PROJECT_ID=my-project # Optional
NODE_ENV=production # OptionalPer-Route Options (Next.js)
export const POST = withErrorCapture(
async (request) => { /* ... */ },
undefined, // use existing client config
{
statusCode: 400,
metadata: { operation: "createUser" },
shouldCapture: (error) => error.name !== "ValidationError",
}
);Automatic Sanitization
The SDK redacts sensitive data from headers, request bodies, and query params.
Built-in redacted fields:
password, secret, token, apikey, api_key, apiKey, authorization, auth, credential, private, credit_card, creditcard, card_number, cvv, ssn, social_security
Always-redacted headers:
authorization, cookie, set-cookie, x-api-key, x-auth-token, proxy-authorization
Add custom fields via the redactFields config option.
Error Resilience
The SDK never interferes with your application:
- Network failures — Silently retried (up to 5 times with exponential backoff)
- Timeouts — Configurable, defaults to 5 seconds
- SDK errors — Caught and logged in debug mode, never thrown to your app
- Original error preserved — The wrapper re-throws the original error so your framework handles the response normally
Captured Data
Each error report includes:
| Field | Description |
|-------|-------------|
| id | Unique error ID |
| fingerprint | Stable hash for deduplication |
| name | Error type (TypeError, etc.) |
| message | Error message |
| stack | Full stack trace |
| stackFrames | Parsed stack frames with file, line, column |
| route | API route path |
| method | HTTP method |
| statusCode | HTTP status code |
| url | Full request URL |
| queryParams | Sanitized query parameters |
| requestBody | Sanitized request body |
| requestHeaders | Sanitized headers |
| routeParams | Dynamic route parameters |
| environment | Environment name |
| projectId | Project identifier |
| metadata | Custom metadata |
TypeScript
All types are exported:
import type {
ErrorCaptureConfig,
CapturedError,
StackFrame,
RouteOptions,
RouteContext,
ErrorReportPayload,
SourceContext,
} from "bugstack-sdk";Compatibility
- Next.js: 14.0.0+
- Express: 4.x or 5.x
- Node.js: 18.0.0+
- TypeScript: 5.0.0+ (optional)
License
MIT
