zentient results api reference Error Handling - ulfbou/Zentient.Results GitHub Wiki

🛠️ Working with Results – Error Inspection & Handling

Location: 🔧 Working with Results Module: Zentient.Results Available since: v0.1.0


📖 Summary

This page outlines the core mechanisms for inspecting, querying, and responding to errors in a result-centric workflow. Zentient.Results enforces structured error propagation through immutable ErrorInfo records, ensuring rich diagnostic context and protocol-agnostic reliability.

From validation to internal exceptions, all failures in Zentient.Results are expressed through strongly typed, metadata-rich objects—not thrown exceptions or opaque strings.


🧩 Structured Error Model

All result errors are encapsulated as ErrorInfo records. Each error provides:

Property Description
Code A string identifier (e.g., VALIDATION_ERROR, RESOURCE_NOT_FOUND)
Message A human-readable summary of the issue
Category A semantic category (e.g., Validation, Conflict, Internal)
Detail Optional extended description
Metadata A dictionary of additional machine-parsable context
InnerErrors Optional nested list of child ErrorInfo instances

See ErrorInfo for full reference.


🔍 Inspecting a Result for Errors

if (result.IsFailure)
{
    logger.LogError("Operation failed: {Error}", result.ErrorMessage);
    foreach (var error in result.Errors)
    {
        Console.WriteLine($"[{error.Category}] {error.Code} → {error.Message}");
    }
}

ErrorMessage provides a shortcut to the first error’s Message property, useful for UIs and logs.


🔖 Common Error Codes

Code Category Description
VALIDATION_ERROR Validation Indicates input validation failure
RESOURCE_NOT_FOUND NotFound The requested entity does not exist
UNAUTHORIZED_ACCESS Authentication The user is not authenticated
FORBIDDEN_ACCESS Authorization The user lacks necessary permissions
BUSINESS_LOGIC_ERROR BusinessLogic A domain rule or invariant was violated
UNHANDLED_EXCEPTION InternalError A caught but unexpected exception occurred
EXTERNAL_SERVICE_ERROR ExternalService A downstream or third-party system failed

Full list: ErrorCodes


⚙️ Metadata Usage

ErrorInfo records can carry structured metadata for diagnostic enrichment:

foreach (var error in result.Errors)
{
    if (error.Metadata.TryGetValue("exceptionType", out var type))
    {
        Console.WriteLine($"Exception: {type}");
    }
}
Metadata Key Purpose
exceptionType Full name of the exception type (if any)
exceptionMessage Exception message string
validationErrors List of validation messages or keys
originalRequestUri Useful for API error tracking

See: MetadataKeys


🧪 Examples

Handle Validation Failures Gracefully

if (result.Status.Code == 422) // Unprocessable Entity
{
    var validationMessages = result.Errors
        .Where(e => e.Category == "Validation")
        .Select(e => e.Message);

    return BadRequest(new { Errors = validationMessages });
}

Nested Error Reporting

foreach (var error in result.Errors)
{
    Console.WriteLine(error.Message);

    if (error.InnerErrors?.Any() == true)
    {
        foreach (var inner in error.InnerErrors)
            Console.WriteLine($"  ↳ {inner.Message}");
    }
}

✅ Best Practices

Guideline Rationale
Avoid using exceptions for control flow Use Result.Failure(...) and inspect via IsFailure
Always enrich domain or infrastructure errors Use Metadata for stack trace, exception type, context
Normalize with ErrorCodes and ResultStatus Enables protocol-safe mappings and logging consistency
Preserve immutability Never mutate result objects or their error collections

📚 See Also


🏷️ Tags

#ErrorHandling #Diagnostics #Validation #ZentientCore #StableContract


Last Updated: 2025-06-22 Version: 0.4.0