Reviewing generated codes
Commit your error codes as a list, and make a divergence fail the build rather than a rename change a wire contract silently.
Reviewing your codes as a list
An error code is a wire contract, and the thing that makes one hard to hold onto is that a rename changes it silently. You can make the whole set reviewable by committing it.
Add an ErrorCodes.txt to the project and list it as an AdditionalFiles item:
<ItemGroup>
<AdditionalFiles Include="ErrorCodes.txt"/>
</ItemGroup>That is the whole opt-in — the same shape as PublicAPI.Shipped.txt for the public API analyzers. A project without the file never sees either rule.
The file is one code per line. Blank lines are ignored and a line starting with # is a comment:
# Every error code this project publishes. Reviewed on change.
order.already-shipped
order.not-foundTwo rules then keep it honest:
WM2019
An enum member generates a code the file does not list
WM2020
The file lists a code no catalog generates
WM2019 has a code fix, Update ErrorCodes.txt, which rewrites the whole file from the compilation: it adds every missing code and removes every stale entry in one pass, sorted, keeping your leading comment block. So a rename shows up as one removed line and one added line, and you read it in the diff before you commit it.
Making a divergence fail the build
Both rules ship as suggestions, so by default they show in the IDE and not in CI. If you have committed the file you probably want the opposite. WM2019 responds to an ordinary .editorconfig:
WM2020 does not. It is reported against ErrorCodes.txt, which has no syntax tree, and Roslyn resolves dotnet_diagnostic severities per syntax tree — so a path-matched section is never consulted for it, including [*]. Raising it takes a global analyzer config:
Put that in a .globalconfig next to the project. A global config covers both rules, so it is the simpler thing to write even though only one of them needs it.
Renaming is a breaking change
The code is built from two names: the enum's and the member's. Rename either (or edit the format) and every consumer reading the code sees a different string, with nothing in the compiler to tell you.
This is not new — ErrorCode.FromEnum worked the same way, and ErrorCode's own guidance is that a code should not change between occurrences of the same error. Treat an attributed enum as a published contract, the way you would treat a URL.
Last updated
Was this helpful?