Skip to content

chore(api): tighten error responses + document response patterns - #191

Merged
patrickrb merged 1 commit into
mainfrom
cleanup/api-error-shapes
May 11, 2026
Merged

chore(api): tighten error responses + document response patterns#191
patrickrb merged 1 commit into
mainfrom
cleanup/api-error-shapes

Conversation

@patrickrb

Copy link
Copy Markdown
Owner

Summary

Two concrete issues with error response bodies; both touched lightly so the PR stays small.

1. Awards routes stop leaking raw error.message (4 files)

src/app/api/awards/{dxcc,was}/{progress,summary}/route.ts had catch blocks returning error: error instanceof Error ? error.message : 'Internal server error' inside their typed responses. A failure on a DB query can surface column names, constraint names, or stack frames in the response body — useful in dev, a soft information-disclosure in prod. Fixed: the real error stays in console.error for server-side observability; the client gets 'Internal server error'.

2. LoTW download routes drop debug: {...} blocks (2 files)

src/app/api/lotw/download{,-contact}/route.ts returned a debug: object alongside credential-error responses, exposing has_username/has_password/credential_source/station identifiers. Leftover from the QRZ debug-strip pass (#189) — the frontend never consumed these fields.

What I deliberately did not change

  • { success, data, error } discriminated union in /api/awards/* stays. Four frontend components branch on data.success; it's an established contract.
  • /api/cloudlog/* { success, ...} responses stay. It's a public Cloudlog-compatible API for 3rd-party logging software — changing the shape breaks integrations.
  • details: field on install/cron error responses stays. Admin/diagnostic flow only, not reachable by untrusted callers.

CLAUDE.md

Updated to document:

Test plan

  • npm run lint → unchanged from baseline (chore(lint): drive ESLint warnings to zero #190 still pending merge)
  • npm run typecheck → clean
  • npm run build → succeeds
  • Manual: hit a DXCC/WAS award summary, simulate failure (e.g. drop a DB connection) — confirm response shows generic error, server log shows actual
  • Manual: try LoTW per-contact download with missing creds — confirm error message displays, no debug: block in DevTools

🤖 Generated with Claude Code

Two concrete issues in error response bodies:

1. Awards routes (4 files) leaked raw error.message to clients in their
   typed `{ success: false, error }` responses. A catch over a DB query
   can surface column names, constraint names, or stack frames in the
   response body — useful in dev, a soft information disclosure in prod.
   Fixed: the real error stays in console.error for server-side
   observability; the client gets 'Internal server error'.

2. LoTW download routes (2 files) returned a `debug: {...}` object
   alongside credential-error responses, exposing internal state like
   `has_username: bool`, `credential_source`, and station identifiers
   to a 400 response. Leftover from the QRZ sync debug-strip pass
   (#189) — the frontend never consumed these fields. Stripped.

The discriminated-union `{ success, data, error }` shape used by
`/api/awards/*` and `/api/cloudlog/*` stays — they're documented
contracts with multiple consumers (frontend checks `data.success`;
cloudlog is a public Cloudlog-compatible API). The `details:` field
on install/cron error responses also stays — it's admin/diagnostic
flow and not reachable by untrusted callers.

CLAUDE.md updated:
- Documents both acceptable response patterns and when each applies
- Adds explicit "don't leak raw error.message" rule with an example
- Notes the cloudlog/* external API contract
- Refreshed the Logging section now that the no-console rule (from
  #189) has landed; points new code at src/lib/logger.ts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented May 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nodelog Ready Ready Preview, Comment May 11, 2026 0:51am

Request Review

@patrickrb
patrickrb merged commit 8292cf4 into main May 11, 2026
7 checks passed
@patrickrb
patrickrb deleted the cleanup/api-error-shapes branch May 11, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant