Skip to content

fix(runner): wrap document load failures in DocumentLoadError - #296

Merged
char0n merged 3 commits into
mainfrom
fix/272-wrap-unreadable-entry-document
Oct 30, 2026
Merged

char0n merged 3 commits into
mainfrom
fix/272-wrap-unreadable-entry-document

Conversation

@char0n

@char0n char0n commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Description

DocumentRegistry.acquire now wraps any error that a provider raises while reading or parsing a document, unless it is already an ArazzoRunnerError, in a new public DocumentLoadError. The new error carries:

  • uri: the canonical URI that failed to load;
  • cause: the original ApiDOM ResolveError or parser ParseError.

Because every acquisition goes through acquire, this covers both cases from the issue:

  • the entry document (ArazzoRunner.load, DocumentRegistry.acquireEntryDocument);
  • a source description acquired when a step first needs it.

Also in this PR:

  • DocumentLoadError is exported from src/index.ts with @public.
  • ArazzoRunner.load lists it in its @throws.
  • The runner README says every thrown error extends ArazzoRunnerError.

Motivation and Context

Closes #272

This was the only failure the runner let escape outside its ArazzoRunnerError hierarchy. Now a single instanceof ArazzoRunnerError check covers every way a run can fail to start.

Website: _reference/runner.md needs updating after this is released:

  • Errors table (lines 809–816): add a DocumentLoadError row.
  • Line 818: delete "A document that cannot be read at all … throws the parser's own error".
  • Optional: mention DocumentLoadError on line 340 (acquireEntryDocument) and line 170 (errors list).

How Has This Been Tested?

  • New DocumentRegistry specs: an unreadable entry document and an unreadable source description both throw DocumentLoadError, with the canonical uri and a non-runner cause. The registry stays usable after the failure.
  • New ArazzoRunner.load spec: an unreadable document rejects with a DocumentLoadError that is also an ArazzoRunnerError.
  • cd packages/runner && npm test: 702 passing. typescript:check-types, typescript:declaration and lint are clean.

Checklist

My PR contains...

  • No code changes (src/ is unmodified: changes to documentation, CI, metadata, etc.)
  • Dependency changes (any modification to dependencies in package.json)
  • Bug fixes (non-breaking change which fixes an issue)
  • Improvements (misc. changes to existing features)
  • Features (non-breaking change which adds functionality)

My changes...

  • are breaking changes to a public API (config options, System API, major UI change, etc).
  • are breaking changes to a private API (Redux, component props, utility functions, etc.).
  • are breaking changes to a developer API (npm script behavior changes, new dev system dependencies, etc).
  • are not breaking changes.

Documentation

  • My changes do not require a change to the project documentation.
  • My changes require a change to the project documentation.
  • If yes to above: I have updated the documentation accordingly.

Automated tests

  • My changes can not or do not need to be tested.
  • My changes can and should be tested by unit and/or integration tests.
  • If yes to above: I have added tests to cover my changes.
  • If yes to above: I have taken care to cover edge cases in my tests.
  • All new and existing tests passed.

A document the registry could not read or parse escaped as ApiDOM's
ResolveError or the parser's ParseError, the only failure outside the
ArazzoRunnerError hierarchy. DocumentRegistry.acquire now wraps any
non-runner error raised by a provider in the new DocumentLoadError,
carrying the canonical URI and the original error as cause. This covers
the entry document and source descriptions acquired during a run.

Refs #272

Signed-off-by: Vladimir Gorej <vladimir.gorej@gmail.com>
Address the adversarial review of #296: test that a runner error
thrown by a provider passes through unwrapped, that an unresolvable
reference in a source description is wrapped, and assert uri and cause
on the source description case. Document DocumentLoadError on
DocumentRegistry.acquire and acquireEntryDocument, and describe it as
a read or load failure: a malformed file still has no matching
provider and throws UnmatchedProviderError.

Refs #272

Signed-off-by: Vladimir Gorej <vladimir.gorej@gmail.com>
@char0n

char0n commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

Adversarial review (lean profile)

Run wf_c8e0bbc2-7f4: 3 dimensions (correctness, issue fit and public API, tests), 16 agents, 0 failures.
Counts: 15 survived, 0 refuted, 0 no-quorum, 9 unrefuted (miss-challenge). 3 survivors carried a dissenting vote; arbitration decided all of them.

Blockers: none.

Suggestions

  • Pass-through branch untested. The instanceof ArazzoRunnerError rethrow in DocumentRegistry.acquire had no test, so deleting it left every test green.
  • Load path untested. Only a missing file was tested; nothing covered a failure inside provide().
  • Wording vs behaviour (unrefuted). A syntactically malformed file is not a DocumentLoadError: no provider's canParse accepts it, so it still throws UnmatchedProviderError with no cause. The docs said "cannot be read or parsed", which promised more than the code does.

Nits

  • Missing @throws. DocumentRegistry.acquire and acquireEntryDocument didn't document DocumentLoadError.
  • Weak assertions. The source-description test didn't assert uri or cause, and the "registry stays usable" test swallowed its error in an empty catch.
  • Not applied: the message doesn't repeat the cause's text (it is on cause), and a programming error inside a provider is also wrapped (the original is kept as cause).

Auto-applied fixes

Commit ea2bc97:

  • New test: a provider that throws a runner error has it passed through unwrapped. Mutation-checked: the test fails when the guard is removed.
  • New test: an OpenAPI source with an unresolvable $ref (a failure inside provide()) throws DocumentLoadError with uri and cause.
  • The source-description test now asserts uri and cause; the "registry stays usable" test asserts the failure instead of swallowing it.
  • @throws added to DocumentRegistry.acquire and acquireEntryDocument.
  • TSDoc, the code comment and the README now say "read or loaded (a missing file, an HTTP error, an unresolvable reference)". A malformed file keeping UnmatchedProviderError is existing behaviour, left as is.

Runner suite: 702 passing. typescript:check-types, typescript:declaration and lint are clean.

@char0n
char0n merged commit ad2307d into main Oct 30, 2026
8 checks passed
@char0n
char0n deleted the fix/272-wrap-unreadable-entry-document branch October 30, 2026 13:47
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.

runner: wrap an unreadable entry document in a runner error

1 participant