Error Handling¶
Package: Asdamir.Core · Namespace: Asdamir.Core.ErrorHandling
Introduction¶
Asdamir favours explicit, structured errors over unhandled exceptions:
- A functional
Resulttype for expected failures. - A global exception middleware that converts anything uncaught into an RFC-7807 ProblemDetails response.
- Multi-language error translation so clients receive a localized, safe message.
- A dead-letter queue (DLQ) for failures that must not be lost.
Registration¶
builder.Services.AddGlobalExceptionHandling();
...
app.UseGlobalExceptionHandling(); // place early so it wraps the whole pipeline
This is also included in the AddFramework() / UseFramework() umbrella.
ProblemDetails mapping¶
Uncaught exceptions are mapped to a ProblemDetails body by IProblemDetailsMapper. The default mapper:
- maps
DomainException(and known infrastructure exceptions) to the right status code, - sets a stable
typeURN and anExtensions["code"]error code, - localizes the
Titlevia the error-translation service, - never leaks raw exception messages, stack traces or backend/library versions.
throw new DomainException("orders.not_found", "Order was not found.");
// → 404 ProblemDetails { type, title (localized), extensions.code = "orders.not_found" }
The Result type¶
Use Result / Result<T> for expected, non-exceptional failures:
public async Task<Result<Order>> GetAsync(Guid id)
{
var order = await _repo.FindAsync(id);
return order is null
? Result<Order>.Fail("orders.not_found")
: Result<Order>.Ok(order);
}
Error translation¶
IErrorTranslationService resolves an error key + language to a localized message, with fallbacks (requested culture → English → generic). Translations are sourced from the database, so operations can edit them without a redeploy.
Dead-letter queue¶
Failures that cannot be retried inline are written through IDlqWriter (a file-backed writer ships by default) so they can be inspected and replayed rather than silently dropped.
Correlation¶
Every request carries a correlation ID (see Observability); it flows into logs, ProblemDetails and outbound HTTP calls so a single failure can be traced end-to-end.