Skip to content

v0.4.0

Choose a tag to compare

@dany-fedorov dany-fedorov released this 18 Sep 16:56
· 60 commits to main since this release

Six opt-in controls over what a failure discloses, and one breaking change: the diagnostic report format. A caller that uses none of the new options sees no other difference from 0.3.0.

Breaking

  • The diagnostic report's v is now corj/v0.13, and its schema ships as schemas/diagnostic-report-v4.json. schemas/diagnostic-report-v3.json stays published, unchanged, for readers of 0.3.0 reports. The public report is still appex/public/v3.
  • The runtime dependency is caught-object-report-json ^10.0.0.
  • TypeScript unions widen with the format: ReportingError['stage'] gains 'redact'; corj's children_omitted gains 'not_inspected' and 'redacted'; as_string_format gains 'derived'.
  • The re-exported restoreExpectedValues (now corj 10) no longer relabels a stored corj/v0.12 report as -full.

New

  • toReports(caught, { occurrenceId, diagnostic, public }) resolves one occurrence and returns both reports from it, so occurrence_id matches for every caught value, thrown primitives included. Options are validated before either report is built; a half pair is never returned. (#45)
  • maxFinalReportSize bounds the whole diagnostic report in UTF-8 bytes of compact JSON. It drops context, then reporting_errors — both named in the new report_omitted field — then shrinks corj's own budget, and throws APPEX_REPORT_BUDGET_TOO_SMALL rather than emit an over-budget or invalid report. (#44)
  • createRedactionPolicy({ keys, paths, patterns, replacement, transform }), accepted as redact by all three report functions. Skip rules (keys, paths) name properties that are never read, so an excluded getter never runs. Scrub rules (patterns, transform) rewrite strings and property names in both reports. To remove a secret's text, use patterns: skipping message still leaves it in stack. On a public report the policy is given only what the kind's details selector returned. A policy that throws fails closed, and its own message is withheld because it can quote what the policy was protecting. (#43)
  • defineException({ snapshotDetails: true }) captures a deep frozen copy of the details at construction, so later mutation of the caller's objects cannot change what the message and the reports describe. It never freezes the caller's objects, and rejects what it cannot capture faithfully — cycles, functions, accessors, class instances — as APPEX_INVALID_DETAILS naming the path. (#47)
  • createTrustRealm() and isTrustedException(caught, realm): an explicit, capability-based trust boundary between separately loaded copies of the package. Trust is keyed by object identity only, so a forged _tag or brand and a wire-deserialized value acquire nothing. Without a realm every copy keeps its isolation, and isTypedException keeps its one-argument shape. (#46)
  • Runtime support, measured: Node >= 18 (CommonJS), Node ESM, Bun, and browsers through a bundler, each exercised against the packed artifact — including a Vite build run in headless Chromium with no Node shims. (#48)
  • A diagnostic report now always carries v, even at the smallest size a budget can force.
  • New error codes: APPEX_REPORT_BUDGET_TOO_SMALL, APPEX_INVALID_TRUST_REALM, APPEX_INVALID_REDACTION_POLICY.

Read more

Recipes · API card · Redaction design · Cross-copy trust design · Runtime support · Changelog

Install: npm install application-exception@0.4.0

npm package