penpot/.serena/memories/scripts/error-reports.md
2026-07-25 09:56:38 +02:00

9.3 KiB
Raw Permalink Blame History

Error Reports CLI Tool

scripts/error-reports.mjs is a Node.js CLI tool for querying Penpot error reports via the RPC API. Provides access to error logs with filtering, pagination, and multiple output formats.

When to use

  • Querying error reports from the database for debugging or analysis
  • Filtering errors by source, kind, tenant, or backend version
  • Exporting error data in JSON, NDJSON, or table format
  • Computing error statistics (top signatures, version, source, audit-log kind, hourly distribution, bursts, heatmap)
  • Investigating specific error reports by ID

Prerequisites

  • Node.js with commander and dotenv packages installed (in root package.json)
  • Running Penpot backend with error-reports RPC endpoints
  • Access token with error-reports:read permission

Configuration

Create a .env file in the project root:

PENPOT_API_URI=http://localhost:3450
PENPOT_ACCESS_TOKEN=<your-token>

Grant the required permission to your access token:

UPDATE access_token
SET perms = ARRAY['error-reports:read']::text[],
    updated_at = now()
WHERE id = '<token-uuid>';

Usage

./scripts/error-reports.mjs <command> [options]

Commands

list - List error reports with pagination and filters

./scripts/error-reports.mjs list [options]

Options:

Flag Description Default
-l, --limit <n> Max items per page (max: 200) 50
--from <date> ISO timestamp — oldest boundary (items after this)
--to <date> ISO timestamp — newest boundary (items before this)
--since <date> ISO timestamp — explicit cursor for manual pagination
--since-id <uuid> Fetch errors after this ID (cursor pagination)
-s, --source <name> Filter by source (see source names below)
-p, --profile-id <uuid> Filter by profile ID
-k, --kind <kind> Filter by kind (string)
-t, --tenant <tenant> Filter by tenant (string)
--version <version> Filter by version
--hint <text> Filter by hint (ILIKE match)
-a, --all Fetch all pages automatically (streams output) false
-f, --format <type> Output format: json, table, or ndjson table
--normalize-hints Normalize hints by stripping dynamic values false
-o, --output <file> Write output to file instead of stdout
--env <path> Custom .env file path .env
-h, --help Show help message

Streaming behavior: With --all, output must be ndjson or table; --all --format json is rejected because --all streams output. --all --format table prints rows immediately. --format ndjson always streams one JSON object per line.

get - Get a single error report by ID

./scripts/error-reports.mjs get [options]

Options:

Flag Description Required
--id <uuid> Error report ID Yes (or --error-id)
--error-id <id> Error report error-id Yes (or --id)
-f, --format <type> Output format: json or table No (default: table)
--env <path> Custom .env file path No (default: .env)
-h, --help Show help message No

stats - Compute error report statistics

./scripts/error-reports.mjs stats [options]

Reads from --input <file>, stdin (piped), or fetches from API. Computes aggregations by signature, version, source, audit-log kind, hour, optional 5-minute bursts, and optional day-of-week × hour heatmap.

Options:

Flag Description Default
--from <date> Start of interval (ISO timestamp)
--to <date> End of interval (ISO timestamp)
--limit <n> Items per page when fetching from API 200
--input <file> Read from local JSON/NDJSON file instead of API
--burst Detect 5-minute windows above 3× the average rate false
--heatmap Show day-of-week × hour-of-day heatmap false
-f, --format <type> Output format: json or table table
--env <path> Custom .env file path .env

Source Names

The --source filter accepts these values:

  • logging
  • audit-log
  • rlimit

Hint Normalization

With --normalize-hints (or always in stats), hints are normalized by stripping dynamic values:

  1. File IDs in file-id context → <file-id>
  2. UUIDs (8-4-4-4-12 hex) → <uuid>
  3. Numeric IDs in parentheses (12345)(<id>)
  4. Elapsed times (7.5s, 2m3.027s) → <elapsed>
  5. URIs (https://...) → <uri>
  6. Unicode quotes and whitespace normalized

Examples

List recent errors

./scripts/error-reports.mjs list --limit 10

Time-range query (today)

./scripts/error-reports.mjs list --from 2026-07-23T00:00:00Z --to 2026-07-23T23:59:59Z --all

Stream all errors as NDJSON

./scripts/error-reports.mjs list --all --format ndjson > errors.ndjson

Save to file with --output

./scripts/error-reports.mjs list --all --format ndjson -o errors.ndjson
./scripts/error-reports.mjs list --format json -o errors.json

Filter by source

./scripts/error-reports.mjs list --source audit-log --limit 20

Filter by kind

./scripts/error-reports.mjs list --kind exception-page

Filter by tenant

./scripts/error-reports.mjs list --tenant production

Filter by version

./scripts/error-reports.mjs list --version 2.1.0

Search by hint (partial match)

./scripts/error-reports.mjs list --hint "NullPointerException"

Fetch all errors with pagination

./scripts/error-reports.mjs list --all

Get specific error by ID

./scripts/error-reports.mjs get --id 550e8400-e29b-41d4-a716-446655440000

Output as JSON

./scripts/error-reports.mjs list --limit 5 --format json

Combine filters

./scripts/error-reports.mjs list --source audit-log --kind exception-page --tenant production --limit 50

Stats with burst and heatmap analysis

./scripts/error-reports.mjs stats --from 2026-07-23T00:00:00Z --to 2026-07-23T23:59:59Z --burst --heatmap

Stats from file

./scripts/error-reports.mjs stats --input errors.json

Stats from pipe

./scripts/error-reports.mjs list --all --format json | ./scripts/error-reports.mjs stats

Output Formats

Table (default)

Human-readable table format for terminal display. With --all, rows stream as they arrive.

JSON

Single page: {items: [...], nextSince, nextId}. --all cannot be combined with --format json; use --format ndjson for streaming.

NDJSON

One JSON object per line, always streaming. Pipe-friendly: | jq -c '.hint', | wc -l.

Pagination

The server returns items in ascending order (oldest first). Cursor pagination uses --since / --since-id to fetch the next page of newer items.

Manual pagination

Use --since and --since-id with values from nextSince and nextId in the response:

./scripts/error-reports.mjs list --limit 50
# Use nextSince and nextId from response
./scripts/error-reports.mjs list --limit 50 --since "2026-01-20T10:29:00Z" --since-id "next-uuid"

Automatic pagination

Use --all to fetch all pages automatically (streams output):

./scripts/error-reports.mjs list --all

Time-range queries

Use --from and --to to bound the query. These map to the server's --since and --until parameters:

./scripts/error-reports.mjs list --from 2026-07-20T00:00:00Z --to 2026-07-23T23:59:59Z --all

Key principles

  • Authentication required - Uses access token with error-reports:read permission
  • API endpoint configurable - Set via PENPOT_API_URI in .env file
  • Table is default format - Use --format json for structured JSON, --format ndjson for streaming
  • Streaming with --all - Items print as they arrive, no buffering. Use --format ndjson or --format table; --all --format json is rejected.
  • Filters are combinable - All filter options can be used together
  • Both flag formats supported - --option=value and --option value both work
  • Ascending order - Server returns oldest items first (changed from DESC)

Error handling

The tool provides helpful error messages for common issues:

  • Missing configuration: Shows setup instructions for .env file
  • Authentication errors (401): Indicates invalid or expired token
  • Authorization errors (403): Indicates missing error-reports:read permission
  • RPC errors: Displays error code and message from the API

Integration with other scripts

  • jq: Pipe NDJSON output to jq for further processing
    ./scripts/error-reports.mjs list --all --format ndjson | jq -c '{id, hint}'
    
  • stats from pipe: Fetch data once, compute stats
    ./scripts/error-reports.mjs list --all --format ndjson | ./scripts/error-reports.mjs stats
    
  • stats from NDJSON pipe: Works with NDJSON format too
    ./scripts/error-reports.mjs list --all --format ndjson | ./scripts/error-reports.mjs stats
    
  • grep/search: Filter output by specific patterns
  • --output: Save to file without shell redirection
    ./scripts/error-reports.mjs list --all --format ndjson -o errors.ndjson