Designing Error Responses
A good error response helps developers understand what went wrong and how to fix it. Let's learn how to design clear, consistent, and helpful error responses.
What Makes a Good Error Response?
A good error response should:
- Use the correct HTTP status code
- Provide a clear error message
- Include an error code for programmatic handling
- Give details about what went wrong
- Suggest how to fix the problem (when possible)
Basic Error Response Structure
Here's a solid error response format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request body contains invalid data",
"details": [
{
"field": "email",
"message": "Invalid email format"
},
{
"field": "age",
"message": "Must be a positive number"
}
]
}
}
Error Response Components
1. Error Code
A machine-readable code that clients can use to handle specific errors:
{
"error": {
"code": "INSUFFICIENT_FUNDS",
"message": "Cannot complete purchase"
}
}
Common code patterns:
VALIDATION_ERRORRESOURCE_NOT_FOUNDAUTHENTICATION_REQUIREDPERMISSION_DENIEDRATE_LIMIT_EXCEEDEDDUPLICATE_RESOURCE
2. Human-Readable Message
A clear message explaining what went wrong:
{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "The user with ID 123 was not found"
}
}
3. Field-Level Details
For validation errors, specify which fields have problems:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "password",
"code": "TOO_SHORT",
"message": "Password must be at least 8 characters"
},
{
"field": "username",
"code": "ALREADY_EXISTS",
"message": "This username is already taken"
}
]
}
}
4. Request ID
Include a request ID for debugging:
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred",
"requestId": "req_abc123xyz"
}
}
5. Documentation Link
Point to documentation for more info:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"documentation": "https://api.example.com/docs/rate-limits"
}
}
Complete Examples
Validation Error (400/422)
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request contains invalid data",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "Must be a valid email address",
"value": "not-an-email"
},
{
"field": "birthDate",
"code": "INVALID_DATE",
"message": "Must be in ISO 8601 format (YYYY-MM-DD)"
}
]
}
}
Authentication Error (401)
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
Content-Type: application/json
{
"error": {
"code": "INVALID_TOKEN",
"message": "The access token has expired",
"documentation": "https://api.example.com/docs/authentication"
}
}
Not Found Error (404)
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "User with ID 'abc123' not found",
"resource": "user",
"identifier": "abc123"
}
}
Server Error (500)
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred. Please try again later.",
"requestId": "req_xyz789"
}
}
Exercise: Build Error Responses
Loading JavaScript Exercise...
Anti-Patterns to Avoid
Don't: Return 200 with error in body
// Bad
HTTP/1.1 200 OK
{
"success": false,
"error": "User not found"
}
Don't: Expose sensitive information
// Bad - exposes internal details
{
"error": {
"message": "SELECT * FROM users WHERE id = 123; Error: connection to postgres failed"
}
}
Don't: Use inconsistent formats
// Bad - different formats for different errors
{ "error": "Not found" }
{ "errorMessage": "Invalid input", "errorCode": 400 }
{ "errors": ["Field required"] }
Best Practices
- Be consistent - Use the same error format everywhere
- Be helpful - Include actionable information
- Be secure - Don't expose internal details
- Be specific - Use meaningful error codes
- Be localized - Support error message localization if needed
Summary
A well-designed error response includes:
| Component | Purpose |
|---|---|
| HTTP Status | Indicate error category |
| Error Code | Enable programmatic handling |
| Message | Explain in human terms |
| Details | Specify what's wrong (for validation) |
| Request ID | Enable debugging |
| Documentation | Help developers fix issues |

