errorcore
Database Support

PostgreSQL

errorcore instruments the pg client library automatically when IO recording is active. Queries made through pg.Client or pg.Pool appear in the IO timeline with their duration, statement text, and position relative to the error.

Setup

Initialize errorcore before creating your Postgres client or pool. The SDK patches the query path at startup, so clients created afterward are instrumented automatically.

initialization order
import errorcore from "errorcore";

errorcore.init({
  service: "billing-api",
  transport: { type: "file", path: "./errors.ndjson" },
  allowUnencrypted: true,
});

// create the pool after init()
import pg from "pg";
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });

What gets recorded

Each query in the IO timeline includes:

  • the SQL statement text
  • query duration in milliseconds
  • row count (when available)
  • position in the ordered timeline relative to other IO
IO timeline
 8ms  SELECT * FROM invoices WHERE account_id = $1
14ms  SELECT * FROM payments WHERE invoice_id = $1
19ms  UPDATE invoices SET status = 'failed' WHERE id = $1
22ms  Error thrown: insufficient balance

Bind parameters

Bind parameters are not captured by default. They often contain user-specific data that does not belong in an error package. If you need them for debugging, enable them explicitly:

enabling bind params
errorcore.init({
  service: "billing-api",
  transport: { type: "file", path: "./errors.ndjson" },
  captureDbBindParams: true,
  encryptionKey: process.env.ERRORCORE_KEY,
});

Bind parameters frequently contain sensitive data (user IDs, email addresses, tokens). Only enable this with encryption and a scrub policy that covers your parameter shapes.

Scrubbing

If your SQL statements contain inline values or identifiable table names that constitute sensitive data, use the piiScrubber config to normalize them before they reach the package:

custom scrubber
errorcore.init({
  service: "billing-api",
  transport: { type: "file", path: "./errors.ndjson" },
  encryptionKey: process.env.ERRORCORE_KEY,
  piiScrubber: (key, value) => {
    if (key === "query" && typeof value === "string") {
      return value.replace(/VALUES\s*\(.*?\)/gi, "VALUES (...)");
    }
    return value;
  },
});

On this page