Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ancplua.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

The generator maps ErrorType enum values to HTTP status codes and BCL TypedResults types following RFC 9110 semantics.

ErrorType → HTTP Mapping

ErrorTypeHTTPTitleTypedResults FactoryReturn Type
Validation400Bad RequestValidationProblem(errors)ValidationProblem
Unauthorized401UnauthorizedUnauthorized()UnauthorizedHttpResult
Forbidden403ForbiddenForbid()ForbidHttpResult
NotFound404Not FoundNotFound(problem)NotFound<ProblemDetails>
Conflict409ConflictConflict(problem)Conflict<ProblemDetails>
Failure500Internal Server ErrorInternalServerError(problem)InternalServerError<ProblemDetails>
Unexpected500Internal Server ErrorInternalServerError(problem)InternalServerError<ProblemDetails>
Failure and Unexpected both map to 500, not 422. These are server errors per RFC 9110. For 422, use Error.Custom(422, ...).

Success Type → HTTP Mapping

ErrorOr TypeHTTPTypedResultsUse Case
ErrorOr<T> (value)200Ok<T>GET, PUT returning entity
ErrorOr<Success>200OkGeneric success
ErrorOr<Created>201CreatedPOST without body
ErrorOr<T> + [Post]201Created<T>POST returning entity
ErrorOr<Updated>200OkPUT/PATCH success
ErrorOr<Deleted>204NoContentDELETE success

Custom Error Codes

Use Error.Custom() for status codes not covered by ErrorType:
// Direct mapping to specific TypedResult
Error.Custom(400, "Code", "Description")  // BadRequest<ProblemDetails>
Error.Custom(422, "Code", "Description")  // UnprocessableEntity<ProblemDetails>
Error.Custom(429, "Code", "Description")  // ProblemHttpResult (429)
Error.Custom(503, "Code", "Description")  // ProblemHttpResult (503)

Custom Error Resolution

NumericTypeTypedResults Factory
400BadRequest(problem)
401Unauthorized()
403Forbid()
404NotFound(problem)
409Conflict(problem)
422UnprocessableEntity(problem)
500InternalServerError(problem)
Other 4xx/5xxProblem(statusCode: code)

ProblemDetails (RFC 7807)

All error responses use RFC 7807 ProblemDetails format:
{
  "type": "https://httpstatuses.io/404",
  "title": "Not Found",
  "status": 404,
  "detail": "Todo with ID 123 was not found",
  "code": "Todo.NotFound",
  "traceId": "00-abc123..."
}

Validation Errors

Multiple validation errors aggregate into HttpValidationProblemDetails:
// Multiple validation errors
return new[]
{
    Error.Validation("Name.Required", "Name is required"),
    Error.Validation("Email.Invalid", "Email format is invalid")
};
{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "Name.Required": ["Name is required"],
    "Email.Invalid": ["Email format is invalid"]
  }
}

Union Type Generation

The generator creates Results<...> union types for OpenAPI documentation:
// Handler
[Get("/todos/{id}")]
public static ErrorOr<Todo> GetById(Guid id) { ... }

// Generated union (inferred from possible error types)
Results<Ok<Todo>, NotFound<ProblemDetails>, InternalServerError<ProblemDetails>>
When calling interface/abstract methods, the generator reads [ReturnsError] attributes to build the complete union. See Interface Types with ReturnsError.

BCL Limit

The BCL provides Results<T1, T2, ..., T6> - maximum 6 type parameters. When more types are needed:
  1. IResult fallback - Loses compile-time safety
  2. Consolidate errors - Use ProblemHttpResult for multiple codes
  3. Custom metadata - Implement IEndpointMetadataProvider

Type Deduplication

Failure and Unexpected both map to InternalServerError<ProblemDetails>, so only one appears in the union.

Type Ordering

Types are ordered by status code (ascending):
Results<
    Ok<Todo>,                           // 200
    Created<Todo>,                       // 201
    NoContent,                           // 204
    ValidationProblem,                   // 400
    NotFound<ProblemDetails>,            // 404
    Conflict<ProblemDetails>,            // 409
    InternalServerError<ProblemDetails>  // 500
>

Middleware-Influenced Union Types

The generator adds status codes to the Results<...> union based on middleware attributes:
AttributeAdded to UnionStatus Code
[Authorize]UnauthorizedHttpResult, ForbidHttpResult401, 403
[EnableRateLimiting]StatusCodeHttpResult (429)429
[AllowAnonymous] overrides [Authorize], so 401/403 are NOT added to the union. Similarly, [DisableRateLimiting] overrides [EnableRateLimiting], so 429 is NOT added.
// With [Authorize], the union includes auth failure types
[Get("/admin")]
[Authorize]
public static ErrorOr<string> AdminOnly() => ...

// Generated union includes 401 and 403:
Results<Ok<string>, UnauthorizedHttpResult, ForbidHttpResult>

Security Considerations

401 Unauthorized and 403 Forbidden return no body to prevent information leakage:
// Correct: No body
ErrorType.Unauthorized => TypedResults.Unauthorized()
ErrorType.Forbidden => TypedResults.Forbid()