Skip to main content

Error Types

The ErrorType enum classifies failures and maps directly to HTTP status codes when using Vali-Mediator.AspNetCore.

ErrorType Enum

public enum ErrorType
{
None = 0, // Success
Validation = 1, // 400 Bad Request
NotFound = 2, // 404 Not Found
Conflict = 3, // 409 Conflict
Unauthorized = 4, // 401 Unauthorized
Forbidden = 5, // 403 Forbidden
Failure = 6, // 500 Internal Server Error
}

HTTP Status Code Mapping

ErrorTypeHTTP StatusUse Case
None (success) on Result<T>200 OKValue returned
None (success) on Result204 No ContentVoid success
Validation400 Bad RequestInput validation failed
NotFound404 Not FoundResource doesn't exist
Conflict409 ConflictDuplicate or state conflict
Unauthorized401 UnauthorizedNot authenticated
Forbidden403 ForbiddenNot authorized for this resource
Failure500 Internal Server ErrorUnexpected server-side error

Usage Examples

Validation

public async Task<Result<Guid>> Handle(CreateProductCommand req, CancellationToken ct)
{
if (string.IsNullOrWhiteSpace(req.Name))
{
var errors = new Dictionary<string, IReadOnlyList<string>>
{
{ "Name", new[] { "Product name is required." } }
};
return Result<Guid>.Fail(errors, ErrorType.Validation);
}

// ...
}

NotFound

public async Task<Result<ProductDto>> Handle(GetProductQuery req, CancellationToken ct)
{
var product = await _repo.FindByIdAsync(req.Id, ct);

if (product is null)
return Result<ProductDto>.Fail($"Product '{req.Id}' was not found.", ErrorType.NotFound);

return Result<ProductDto>.Ok(product.ToDto());
}

Conflict

public async Task<Result<Guid>> Handle(CreateUserCommand req, CancellationToken ct)
{
if (await _repo.ExistsByEmailAsync(req.Email, ct))
return Result<Guid>.Fail($"A user with email '{req.Email}' already exists.", ErrorType.Conflict);

// ...
}

Unauthorized / Forbidden

// Not authenticated (no valid credentials)
return Result<OrderDto>.Fail("Authentication required.", ErrorType.Unauthorized);

// Authenticated but not allowed
return Result<OrderDto>.Fail("You don't have permission to view this order.", ErrorType.Forbidden);

Failure (Unexpected Errors)

public async Task<Result<string>> Handle(ProcessPaymentCommand req, CancellationToken ct)
{
try
{
var txId = await _paymentGateway.ChargeAsync(req.Amount, req.CardToken, ct);
return Result<string>.Ok(txId);
}
catch (PaymentGatewayException ex)
{
_logger.LogError(ex, "Payment gateway error for order {OrderId}", req.OrderId);
return Result<string>.Fail("Payment processing failed. Please try again.", ErrorType.Failure);
}
}

Checking Error Type

Result<ProductDto> result = await _mediator.Send(query);

switch (result.ErrorType)
{
case ErrorType.None:
return Ok(result.Value);
case ErrorType.NotFound:
return NotFound(result.Error);
case ErrorType.Validation:
return ValidationProblem(result.ValidationErrors);
default:
return StatusCode(500, result.Error);
}
tip

With Vali-Mediator.AspNetCore, you don't need the switch statement above — just call result.ToActionResult() and it handles all cases automatically.