CodePark/ questions / Client–server contract
START PRACTICINGPRACTICE
Frontend question · Frontend system design › Client–server contract

Design an API error contract that the frontend can rely on. What should an error response contain, and how does the client use it?

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Some fields are invalid",
    "requestId": "req_8f2a",
    "fields": [{ "path": "email", "code": "EMAIL_TAKEN" }],
    "retryable": false
  }
}

Every error should have the same shape, a correct HTTP status, and a stable machine-readable code. The client checks the code, never the human message, because messages change and get translated.

A good error response contains:

  • A stable code, like VALIDATION_FAILED. The client logic switches on it.
  • Field errors with a path, so the form can show each error next to the right input.
  • A requestId. It lets support staff and logs match up the failure.
  • A retry hint, like a retryable flag, or a Retry-After header on 429 and 503 responses. It tells the client whether an automatic retry makes sense.

On the client, I wrap fetch in one API layer. It turns responses into typed errors:

  • network errors
  • 401 (refresh the token or redirect to login)
  • 403
  • 404
  • validation errors
  • server errors

Components then decide how to show the error:

  • inline messages next to fields
  • a toast for short-lived failures
  • an error boundary for a whole page that failed

The text the user reads comes from the client's i18n catalogue (the translated messages), keyed by the error code.

  • Every error has the same shape and a correct status code.
  • Stable error codes, not messages, drive the client logic.
  • Include field-level errors and a request id.
  • Include retry hints such as retryable or Retry-After.
  • A single API layer maps responses to typed errors.