feat(binder): let consumers document their overridden structural errors - #193
Merged
Conversation
A consumer that overrides a structural-error definition owns the effective code and messages, so it must document them in its own catalog. Expose the binder's code-independent prose and a faithful example, parameterised by a BinderErrorDefinition: - DescribeArgumentRequired / DescribeArgumentInvalid — the generic documentation (title, rule, diagnoses) with a live example built from the given definition; - SampleArgumentRequired / SampleArgumentInvalid — the example error itself, for the consumer's [DocumentedBy] factory. The private parameterless documentation methods now delegate to the public overloads with the defaults, so the binder's own catalog is unchanged. The two sample seams return an error without [DocumentedBy] and are suppressed against FCE009 as deliberate non-catalog helpers. Refs: #140 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sD2irTr5PBVpxHt2dkRzQ
Add a subsection to the RequestBinder guide (EN + FR) showing the small [ProvidesErrorsFor] glue that surfaces overridden structural errors in a consumer's own generated catalog, delegating to the public Describe / Sample seams — so the documented entry matches what the binder emits at runtime. Refs: #140 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sD2irTr5PBVpxHt2dkRzQ
Record the decision to close the override half of #140 by having a consumer document its overridden structural errors in its own catalog, via public binder seams, rather than the generator auto-discovering a referenced package's codes. Drafted Proposed (EN + FR) and indexed; auto-discovery stays an open follow-up. Refs: #140 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sD2irTr5PBVpxHt2dkRzQ
Per the maintainer's decision: ADR-0019 is Accepted. Tighten its stance on auto-discovery — since RequestBinder is the only package shipping emittable codes and its binary carries only the defaults, auto-discovery is not deferred but unnecessary (it could never surface a consumer's overrides, and would mislead an overriding consumer). Follow-up is now None. Refs: #140 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sD2irTr5PBVpxHt2dkRzQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A consumer that overrides a binder structural-error definition (ADR-0018) owns the effective code and messages, which live in the consumer's own assembly and are absent from the RequestBinder binary. This adds public seams so the consumer documents those errors in its own generated catalog, reusing the binder's code-independent prose and a faithful example — closing the override half of #140 without any change to the generator.
Type of change
Changes
RequestBindingErrorexposes four public seams, parameterised by aBinderErrorDefinition:DescribeArgumentRequired/DescribeArgumentInvalid(the binder's generic prose with a live example built from the definition) andSampleArgumentRequired/SampleArgumentInvalid(the example error itself, for the consumer's[DocumentedBy]factory).[DocumentedBy]; they are suppressed against FCE009 (dogfooded on the binder) as deliberate non-catalog helpers, with a justification.StructuralErrorDescriptionTests): the samples carry the definition's custom code, messages, and structural shape (context, wrapped cause);Describereuses the binder's title/diagnoses with the custom example; the default-definition path still yieldsREQUEST_ARGUMENT_*.[ProvidesErrorsFor]glue that delegates to the seams.Testing
dotnet build FirstClassErrors.slndotnet test FirstClassErrors.slnFirstClassErrors.Analyzers.UnitTests)All green: 0 warnings/errors under the solution's total
TreatWarningsAsErrorsratchet; 1047 tests passed, 0 failed, across all 9 test projects.Documentation
doc/updateddoc/handwritten/for-users/README.fr.md) updated if user-facing behavior changedThe RequestBinder guide's English and French versions were updated together. The top-level
README.fr.mddoesn't describe binder internals, so it wasn't touched.Architecture decisions
ADR-0019 records documenting overridden binder errors in the consumer's own catalog via these seams, rather than the generator auto-discovering a referenced package's codes — and rules that auto-discovery out (not merely defers it): RequestBinder is the only package shipping emittable codes, its binary carries only the defaults, so auto-discovery could never surface a consumer's overrides. This closes the risk ADR-0016 and ADR-0018 deferred to #140.
Related issues
Refs #140 (closed — the override case is resolved by these seams; auto-discovery ruled out, see ADR-0019)
Generated by Claude Code