π Languages:
π¬π§ English (this file) | π«π· FranΓ§ais
| Build | |
| Quality | |
| Security | |
| Package | |
| Project |
Turn your errors into structured, living knowledge about your system.
An application error too often boils down to a bare code or string, with nothing that explains what it actually means. FirstClassErrors turns it into a first-class concept of your domain. You describe each error situation once, with its rules, in one place in the code; the whole library then builds on that model.
Model the error An error becomes an object that carries its own meaning β a violated business rule, a rejected incoming request, or a failing external service, transient or not.
Handle the failure You choose how it travels: thrown as an ordinary exception, or returned as an explicit result the caller inspects without a try/catch.
Document the error Each error can carry its explanation, its rule, and its likely causes right there in the code. FirstClassErrors generates a human-readable catalog from that same code β so it never drifts.
Check the model Roslyn analyzers enforce these rules at compile time: a duplicated error code or inconsistent documentation becomes a build error, caught before it ever reaches production.
Bind external input A form or a JSON request must become a valid domain object. Where classic .NET binding restates those rules separately, in a validator or attributes, FirstClassErrors binds that input directly to your value objects, reusing their own construction rules instead of duplicating them.
A production error is rarely useful as only a type and a string:
Invalid operation.
Developers and support still need to discover:
- which situation actually occurred;
- which rule was violated;
- which facts belong to this occurrence;
- what might have caused it;
- where to start investigating.
When that knowledge lives in logs, tickets, comments, and people's memories, it drifts away from the code.
A factory gives the error situation a stable identity, keeps its construction in one place, and attaches structured documentation that will feed a generated, human-readable catalog:
[ProvidesErrorsFor(nameof(Amount))]
public static class InvalidAmountOperationError {
[DocumentedBy(nameof(CurrencyMismatchDocumentation))]
internal static DomainError CurrencyMismatch(Amount left, Amount right) {
return DomainError.Create(
ErrorCode.Create("AMOUNT_CURRENCY_MISMATCH"),
diagnosticMessage: $"Cannot add {left} and {right} because their currencies differ.")
.WithPublicMessage(
shortMessage: "The amounts use different currencies.",
detailedMessage: "Both amounts must use the same currency.");
}
private static ErrorDocumentation CurrencyMismatchDocumentation() {
return DescribeError.WithTitle("Amount currency mismatch")
.WithDescription("This error occurs when an operation combines amounts expressed in different currencies.")
.WithRule("A monetary operation must use one common currency.")
.WithDiagnostic(
"The amounts reached the operation without being converted to one currency.",
ErrorOrigin.Internal,
"Verify where the amounts should have been converted before this operation.")
.WithExamples(() => CurrencyMismatch(
new Amount(10, Currency.EUR),
new Amount(12, Currency.USD)));
}
}The domain code stays focused on intent:
if (Currency != other.Currency) {
throw InvalidAmountOperationError.CurrencyMismatch(this, other).ToException();
}The factory returns an Error (DomainError is one of its categories), so expected failures can use the same model without throwing:
return Outcome<Amount>.Failure(
InvalidAmountOperationError.CurrencyMismatch(left, right));From these factories, FirstClassErrors can generate a human-readable catalog for developers, support teams, and operations.
dotnet add package FirstClassErrorsThe package targets .NET Standard 2.0. Its Roslyn analyzers are bundled automatically; no separate analyzer package is required.
To bind incoming requests into typed commands or queries at the primary-adapter boundary, add the optional request binder:
dotnet add package FirstClassErrors.RequestBinderTo generate documentation, install the CLI:
dotnet tool install --global FirstClassErrors.CliThen follow the Getting Started guide to create and generate your first documented error.
FirstClassErrors is especially useful for long-lived application or domain code where:
- errors represent rules, constraints, or boundary failures;
- several teams or systems depend on stable error codes;
- support and operations investigate production failures;
- documentation must remain aligned with behavior.
For prototypes, tiny utilities, or low-level technical code, standard exceptions may be enough. See When Not to Use FirstClassErrors.
The package includes Roslyn rules with stable FCExxx identifiers. They detect duplicate or malformed error codes, invalid documentation wiring, missing examples, and common API misuse. See the analyzer rules reference.
Released packages include signed build provenance and an embedded SPDX SBOM. See the release and verification details in the supply-chain documentation.
Found a bug or want to request a feature? Open an issue on the GitHub issue tracker. Contributions are welcome; see CONTRIBUTING.md.
For security vulnerabilities, follow the private process in SECURITY.md.
- Writing Errors Guide
- Usage Patterns
- Binding requests at the boundary (RequestBinder)
- Best Practices
- Testing Guide
