web
API Error Handling
Implement consistent error handling and responses in APIs.
By Emem IsaacApril 9, 20213 min read
#error handling#api responses#status codes#validation
Share:
A Simple Analogy
Good error handling is like clear signage. It tells users exactly what went wrong and how to fix it.
Why Error Handling?
- Clarity: Users understand what failed
- Debugging: Easier to fix issues
- Security: Don't expose internals
- Consistency: Predictable error format
- Recovery: Guide users to solutions
HTTP Status Codes
2xx Success
- 200 OK: Request succeeded
- 201 Created: Resource created
- 204 No Content: Success, no body
4xx Client Error
- 400 Bad Request: Invalid input
- 401 Unauthorized: Not authenticated
- 403 Forbidden: No permission
- 404 Not Found: Resource missing
- 409 Conflict: State conflict
- 422 Unprocessable: Validation failed
5xx Server Error
- 500 Internal Server Error: Server fault
- 503 Service Unavailable: Temporarily down
Error Response Format
public class ApiError
{
public string Code { get; set; }
public string Message { get; set; }
public Dictionary<string, string[]> Errors { get; set; }
public string TraceId { get; set; }
}
// Success response
public class ApiResponse<T>
{
public T Data { get; set; }
public bool Success { get; set; }
}
// Controller
[HttpPost]
public async Task<ActionResult<ApiResponse<OrderDto>>> CreateOrder(CreateOrderRequest request)
{
if (!ModelState.IsValid)
{
return BadRequest(new ApiError
{
Code = "VALIDATION_ERROR",
Message = "Validation failed",
Errors = ModelState
.Where(x => x.Value.Errors.Count > 0)
.ToDictionary(x => x.Key, x => x.Value.Errors.Select(e => e.ErrorMessage).ToArray()),
TraceId = HttpContext.TraceIdentifier
});
}
try
{
var order = await _service.CreateAsync(request);
return Ok(new ApiResponse<OrderDto> { Data = order, Success = true });
}
catch (ValidationException ex)
{
return BadRequest(new ApiError
{
Code = "INVALID_ORDER",
Message = ex.Message,
TraceId = HttpContext.TraceIdentifier
});
}
}
Global Exception Handling
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.ContentType = "application/json";
var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
var exception = exceptionHandlerPathFeature?.Error;
var response = new ApiError
{
TraceId = context.TraceIdentifier,
Code = "INTERNAL_ERROR",
Message = "An unexpected error occurred"
};
context.Response.StatusCode = exception switch
{
ArgumentException => StatusCodes.Status400BadRequest,
UnauthorizedAccessException => StatusCodes.Status401Unauthorized,
KeyNotFoundException => StatusCodes.Status404NotFound,
InvalidOperationException => StatusCodes.Status409Conflict,
_ => StatusCodes.Status500InternalServerError
};
if (context.Response.StatusCode == StatusCodes.Status500InternalServerError)
{
_logger.LogError(exception, "Unhandled exception");
}
await context.Response.WriteAsJsonAsync(response);
});
});
Problem Details (RFC 7807)
// Modern standard error format
var problemDetails = new ProblemDetails
{
Type = "https://api.example.com/errors/validation-error",
Title = "Validation Failed",
Status = StatusCodes.Status400BadRequest,
Detail = "The order contains invalid items",
Instance = HttpContext.Request.Path
};
problemDetails.Extensions.Add("errors", new
{
items = new[] { "Items list is empty" },
customerId = new[] { "CustomerId is required" }
});
return BadRequest(problemDetails);
Best Practices
- Use appropriate status codes: Be consistent
- Include error details: But not internals
- Provide error codes: For programmatic handling
- Log server errors: But don't expose logs
- Document errors: Show expected errors in API docs
Related Concepts
- API documentation
- Validation frameworks
- Logging and monitoring
- Security best practices
Summary
Implement consistent error responses with appropriate status codes, clear messages, and error codes. Use global exception handling for uniform error responses.
Share:
Related Articles
web
Efficient File Uploads
Handle file uploads securely and efficiently.
Read More webHTTP Status Codes
Learn how to understand and use HTTP status codes effectively in web applications and APIs.
Read More webAngular Component Communication
Implement patterns for component communication in Angular.
Read More