Skip to content

Model GenDoc's own failures as documented first-class errors#163

Merged
Reefact merged 8 commits into
mainfrom
claude/gendoc-firstclasserror-f331kj
Jul 16, 2026
Merged

Model GenDoc's own failures as documented first-class errors#163
Reefact merged 8 commits into
mainfrom
claude/gendoc-firstclasserror-f331kj

Conversation

@Reefact

@Reefact Reefact commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary

GenDoc now models and documents its own failure surface with the FirstClassErrors model it implements: every generator failure carries a stable GENDOC_-prefixed code, structured context, transience and direction, and lands in the catalog generated by the tool itself — dogfooding the library, providing a real (non-sample) reference consumer, and letting CI assert the documentation pipeline end to end.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Analyzer / diagnostic change
  • Tests
  • Documentation
  • Build / CI / tooling

Changes

  • Add DocumentationRequestError (invalid generation requests, PrimaryPortError) and DocumentationToolchainError (SDK/worker failures, SecondaryPortError): 16 documented GENDOC_* codes with typed context keys (ErrCtxKey), diagnostics and executable examples.
  • Rebase SolutionDocumentationGenerationException on DiagnosableException; its constructors now take an Error (plus an optional runtime cause). Core gains a protected DiagnosableException(Error, Exception) constructor preserving the technical cause on Exception.InnerException.
  • Route every throw and HandleFailure site of SolutionErrorDocumentationGenerator through the factories. Timeouts get their own transient code (GENDOC_PROCESS_TIMED_OUT) carrying command, target, timeout and the output captured before the kill; the SDK-query (-getProperty:TargetPath) timeout no longer degrades into a silent project skip; the target-path resolution catch no longer swallows OperationCanceledException nor re-wraps already-coded failures; exit codes render culture-invariantly.
  • Wire the FCE analyzers onto FirstClassErrors.GenDoc (same dogfooding pattern as FirstClassErrors.Usage) and opt the project into catalog generation.
  • CLI: generate, catalog diff and catalog update catch DiagnosableException ahead of the generic handler and report CODE: message through a single shared helper (FailureReporting).
  • CI: the .NET 8 floor job also documents FirstClassErrors.GenDoc.dll and requires GENDOC_ codes in the produced catalog.
  • Tests: per-factory contract tests, exception-contract tests, a self-extraction test asserting the exact 16-code surface with zero failures, generator tests updated to the coded contract, and a CLI test pinning the CODE: message line.

Breaking changes (recorded in the feat(gendoc)! commit):

  • SolutionDocumentationGenerationException(string[, Exception]) constructors are replaced by (Error[, Exception]).
  • GetErrorDocumentationFrom raises SolutionDocumentationGenerationException (codes GENDOC_SOLUTION_NOT_FOUND / GENDOC_SOLUTION_PATH_UNSUPPORTED) where it previously threw FileNotFoundException / ArgumentException.

Testing

  • dotnet build FirstClassErrors.sln
  • dotnet test FirstClassErrors.sln
  • Analyzer tests pass (FirstClassErrors.Analyzers.UnitTests)

Also run: dotnet build -warnaserror (0 warnings); end-to-end fce generate --assemblies FirstClassErrors.GenDoc.dll through the real worker (16 GENDOC_* codes extracted), combined with the Usage sample (26 codes, no collision), and fce generate --solution <missing> verifying the error: GENDOC_SOLUTION_NOT_FOUND: … line and exit code 1. Both were re-verified after merging main back into the branch.

Documentation

  • Public API / error documentation updated
  • README / doc/ updated
  • French translation updated if user-facing behavior changed (doc/DocumentationExtractionReference.fr.md, doc/LoggingIntegration.fr.md, maintainers/adr/0009-….fr.md)
  • No documentation change required

Architecture decisions

  • No architectural decision in this pull request
  • New decision recorded — ADR drafted as Proposed: ADR-0009 (report the tooling's failures as first-class errors; renumbered from 0008 after ADR-0008 landed on main for the binder)
  • Supersedes an existing ADR — successor proposed, status not flipped: ADR-____
  • ⚠️ Conflicts with an existing ADR — flagged for the maintainer: ADR-____

Checked against the ADR base: ADR-0002 respected (no TFM change to the tooling); ADR-0005 noted — the generator keeps its throwing entry point unrenamed for now, an Outcome-returning variant is listed as a follow-up in ADR-0009.

Related issues

Closes #142
Refs #140

🤖 Generated with Claude Code

https://claude.ai/code/session_0148FgVG3MkKn2kudM2TkmGa

claude added 8 commits July 16, 2026 07:51
Add a protected DiagnosableException(Error, Exception) constructor so a
subclass can preserve the technical cause of a failure (an I/O error, a
serialization error...) on Exception.InnerException, with its stack
trace, while the modeled diagnostic tree stays on Error.InnerErrors.

Refs: #142
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148FgVG3MkKn2kudM2TkmGa
Dogfood the library in its own tooling: every failure of the solution
documentation generator is now a first-class error with a stable
GENDOC_-prefixed code, structured context, transience, direction, and
generated documentation.

- add DocumentationRequestError (invalid generation requests, as
  primary-port errors) and DocumentationToolchainError (SDK and worker
  failures, as secondary-port errors), 16 documented codes in total;
- rebase SolutionDocumentationGenerationException on
  DiagnosableException so the raised failure exposes the full error;
- route every throw and HandleFailure site through the factories,
  including the previously bare FileNotFoundException/ArgumentException
  guards and the SDK-query timeout that used to skip a project
  silently; timeouts get their own transient code and keep the output
  captured before the kill;
- wire the FCE analyzers onto the project and opt it into catalog
  generation, so the tool documents itself;
- cover every factory, the exception contract, and the self-extraction
  of the 16 codes in unit tests.

BREAKING CHANGE: SolutionDocumentationGenerationException is now
constructed from an Error instead of a message string, and the
generator raises it (with codes GENDOC_SOLUTION_NOT_FOUND and
GENDOC_SOLUTION_PATH_UNSUPPORTED) where it previously threw
FileNotFoundException or ArgumentException.

Refs: #142
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148FgVG3MkKn2kudM2TkmGa
Catch DiagnosableException ahead of the generic handler in the
generate and catalog commands and render the failure through a single
shared helper, so every command emits the same grep-able
"CODE: message" line that can be looked up in the tool's own catalog.

Refs: #142
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148FgVG3MkKn2kudM2TkmGa
Feed FirstClassErrors.GenDoc.dll to the existing fce generate step and
require GENDOC_ codes in the produced catalog: the .NET 8 floor job now
proves the pipeline end to end against the tool's own error surface.

Refs: #142
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148FgVG3MkKn2kudM2TkmGa
Refs: #142
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148FgVG3MkKn2kudM2TkmGa
The extraction reference now names the GENDOC_ codes and the single
code-led warning a timeout produces, and the logging guide notes the
runtime-cause channel on DiagnosableException.InnerException. French
translations updated in step.

Refs: #142
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148FgVG3MkKn2kudM2TkmGa
…asserror-f331kj

# Conflicts:
#	maintainers/adr/README.md
@Reefact
Reefact enabled auto-merge July 16, 2026 11:28
@Reefact
Reefact merged commit c8c8cd1 into main Jul 16, 2026
12 checks passed
@Reefact
Reefact deleted the claude/gendoc-firstclasserror-f331kj branch July 16, 2026 11:29
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.

GenDoc: model and document its own errors with FirstClassErrors (dogfood the library)

2 participants