Upgrade @arki/log 0.1.0 to 0.2.0
For @arki/[email protected] · source docs/upgrades/0.1.0-to-0.2.0.md
Apps that read isFailure results from untrusted JSON (API responses, queue messages, tool output) must check that nothing relied on a forged failure. Apps that only log can skip this and gain failure logging.
What changed
- Security: outside data can no longer pass as a failure.
isFailure(and@arki/log's failure check) now require the~failurebrand on the value's prototype and refuse it as an own property. Before, JSON such as{"~failure": true, "code": "x", "status": 500}from an API response, queue message or tool result counted as a failure, so boundaries skipped output schemas and answered with an attacker-chosen status or code. Real failures, revived ones and failures from a second copy of the package are still recognised. - A failure value from
@arki/failurecan be logged as a field:log.warn('lookup failed', { failure }). Every formatter and the OpenTelemetry sink print itscode,message,status,dataandremediation, pluscauses: the cause chain, nearest first, through nested failures and thrown errors. The list stops at a cycle ([Circular]) or after 64 links ([MaxDepth]), the same limit asfindCause.redact()paths reach into a failure's data and causes.@arki/logstill has no dependencies: it knows a failure by its'~failure'brand. New exports:serializeFailureand theFailureLiketype, which is now part ofValue.
Public API changes
isFailureand the log failure check require the~failurebrand on the prototype. An own~failureproperty no longer counts.- New exports:
serializeFailureand theFailureLiketype, now part ofValue.
Steps
-
Search for code that builds a failure-shaped object by hand, such as
{ '~failure': true, code, status }. It stops counting as a failure.// before: plain JSON passed as a failure const forged = { '~failure': true, code: 'x', status: 500 }; // after: only values made by @arki/failure (or revived by it) countCreate failures with
@arki/failure. Revive stored ones with its revive function. -
Optional: log failures as fields. Formatters print
code,message,status,data,remediationandcauses.// before log.warn('lookup failed', { code: failure.code, message: failure.message }); // after log.warn('lookup failed', { failure });
Verify
Run bun run test in the app. Then log one failure and check the output shows its code and causes.