UnprocessableException
Namespace: RA.Utilities.Core.Exceptions
The UnprocessableException is a semantic exception used to signal that a requested action cannot be performed because of the current state of a resource.
It is designed to be translated into a standardized HTTP 422 Unprocessable Entity response.
🎯 Purpose
This exception represents a "State Conflict." It is used when the client's request is technically valid (correct format and types), but the server's current data state makes the operation impossible.
Common scenarios include:
- Attempting to delete a resource that is currently "In Use."
- Attempting to transition an entity to a status that is not allowed from its current status (e.g., Shipped → Cancelled).
- Modifying a record that has been "Locked" or "Archived."
- Trying to withdraw $100 when the daily limit is $50 (Business Rule violation).
🚀 How to Use
Throw this exception from your domain services or application handlers when a business rule transition is violated.
Example: Invalid Status Transition
public async Task<Result> CancelOrderAsync(Guid orderId)
{
var order = await _orderRepository.GetByIdAsync(orderId);
if (order == null)
{
return new NotFoundException(nameof(Order), orderId);
}
// Business Rule: Shipped orders cannot be cancelled.
if (order.Status == OrderStatus.Shipped)
{
return new UnprocessableException(
"ORDER_ALREADY_SHIPPED",
"Cannot cancel an order that has already been shipped."
);
}
order.Status = OrderStatus.Cancelled;
await _orderRepository.UpdateAsync(order);
return Result.Success();
}
Example JSON Output
When the API layer handles a Failure Result containing an UnprocessableException, it will automatically generate a 422 response with a body like this:
{
"responseCode": 422,
"responseType": "Unprocessable",
"responseMessage": "Cannot cancel an order that has already been shipped.",
"result": {
"errorCode": "ORDER_ALREADY_SHIPPED",
"message": "Cannot cancel an order that has already been shipped."
}
}