Error Handling

Designing clear, consistent error responses that clients can act on

Overview

Good error handling means every failure returns a correct status code plus a body that explains what went wrong in a consistent shape. This lets client developers detect errors programmatically and show helpful messages to users. A predictable error format is just as important as a predictable success format.

Syntax / Usage

Pair the right 4xx/5xx status code with a structured JSON body. Include a machine-readable code, a human-readable message, and (when useful) field-level details.

{
  "error": {
    "code": "validation_error",
    "message": "One or more fields are invalid",
    "details": [
      { "field": "email", "issue": "must be a valid email" }
    ]
  }
}

Examples

A validation failure returns 400 with per-field details:

POST /users HTTP/1.1

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": {
    "code": "validation_error",
    "message": "Email is required",
    "details": [{ "field": "email", "issue": "required" }]
  }
}

An unexpected failure returns 500 without leaking internals:

{
  "error": {
    "code": "internal_error",
    "message": "Something went wrong. Please try again later."
  }
}

Common Mistakes

  • Returning 200 OK with an error message buried in the body
  • Using different error shapes across endpoints, forcing custom parsing
  • Leaking stack traces or database messages in 500 responses
  • Writing vague messages like "Error" with no actionable detail
  • Omitting a stable machine-readable code clients can branch on

See Also

api-design-status-codes api-design-http-methods api-design-rest-basics