API Design: Error Handling
Effective error handling is crucial for building robust, user-friendly, and maintainable APIs. Clear and consistent error messages help developers integrate with your API smoothly and diagnose issues efficiently.
Core Principles
- Consistency: Use a standardized format for all error responses.
- Clarity: Provide human-readable messages that explain what went wrong.
- Actionability: Suggest steps the client can take to resolve the error.
- Information: Include relevant details like error codes, timestamps, and request IDs.
- Appropriate HTTP Status Codes: Leverage standard HTTP status codes to convey the general nature of the error.
Standard Error Response Format
We recommend a JSON-based error response format that includes the following fields:
JSON Error Response Example
{
"error": {
"code": "INVALID_REQUEST_PARAMETER",
"message": "The 'userId' parameter is missing or invalid.",
"details": "Please provide a valid UUID for the user identifier.",
"target": "userId",
"requestId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"timestamp": "2023-10-27T10:30:00Z"
}
}
Field Definitions:
code
: A unique, machine-readable error code that can be used for programmatic handling.message
: A human-readable description of the error.details
: (Optional) More specific information about the error or how to fix it.target
: (Optional) The specific parameter or resource that caused the error.requestId
: (Optional but recommended) A unique identifier for the request, useful for logging and debugging.timestamp
: (Optional) The time the error occurred.
HTTP Status Codes
Use standard HTTP status codes to indicate the category of the error. Here are some common ones:
400 Bad Request
: The request was malformed or invalid.401 Unauthorized
: Authentication is required and has failed or has not been provided.403 Forbidden
: The authenticated user does not have permission to perform the action.404 Not Found
: The requested resource could not be found.405 Method Not Allowed
: The HTTP method used is not allowed for the requested resource.409 Conflict
: The request could not be completed due to a conflict with the current state of the resource.422 Unprocessable Entity
: The request was well-formed but contains semantic errors.500 Internal Server Error
: A generic error message for unexpected conditions.503 Service Unavailable
: The server is temporarily unable to handle the request.
Always strive to return the most specific 4xx status code applicable.
Common Error Scenarios and Examples
1. Invalid Input
Occurs when a request parameter is missing, has an incorrect format, or an invalid value.
Request:
POST /users
Headers:Content-Type: application/json
Body:{"name": "John Doe", "email": "invalid-email"}
Response (HTTP 400 Bad Request):
{
"error": {
"code": "INVALID_EMAIL_FORMAT",
"message": "The provided email address is not valid.",
"details": "Please ensure the email follows standard format (e.g., user@example.com).",
"target": "email",
"requestId": "xyz789abc-..."
}
}
2. Resource Not Found
Occurs when the requested entity does not exist.
Request:
GET /products/99999
Response (HTTP 404 Not Found):
{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "The product with ID '99999' was not found.",
"target": "/products/99999",
"requestId": "pqr123stu-..."
}
}
3. Authentication/Authorization Issues
For authentication errors (e.g., missing API key), use 401 Unauthorized
. For authorization errors (e.g., user doesn't have permission), use 403 Forbidden
.
Response (HTTP 401 Unauthorized):
{
"error": {
"code": "AUTHENTICATION_FAILED",
"message": "API key is missing or invalid.",
"details": "Please include a valid 'X-API-Key' header.",
"requestId": "uvw456xyz-..."
}
}
Response (HTTP 403 Forbidden):
{
"error": {
"code": "PERMISSION_DENIED",
"message": "You do not have permission to access this resource.",
"details": "Your current role does not allow this operation.",
"requestId": "ghi789jkl-..."
}
}
Best Practices
- Avoid exposing sensitive information in error messages (e.g., stack traces, database error details).
- Document your error codes thoroughly in your API reference.
- Consider providing a list of common error codes and their meanings.
- Log errors on the server-side with correlation IDs for easier debugging.
- Allow clients to request specific error details through an optional query parameter if needed for debugging, but disable this in production.