Skip to main content

Error Handling

Every non-2xx response from the Itqan CMS API uses the same envelope. Build your error handling once and it covers every endpoint.

Error Envelope

{
"error_name": "not_found",
"message": "No asset matches the given query.",
"extra": null
}
FieldTypeDescription
error_namestringStable machine identifier. Switch on this in code, not on message or HTTP status. Never contains spaces.
messagestringHuman-readable description. Localized via Accept-Language — safe to display directly to users.
extraobject or nullOptional structured detail. Shape varies by error type (see catalog below).

Error Catalog

HTTPerror_nameTriggered byextra shape
400validation_errorInvalid query parameters or request bodyArray of field-level error objects
400invalid_jsonMalformed JSON request bodynull
401authentication_errorMissing or invalid credentialsnull
401token_not_validExpired or revoked JWT tokennull
403permission_deniedAuthenticated but not authorizednull
404not_foundResource does not existnull
4xx/5xxhttp_errorGeneric HTTP error pathnull
500internal_errorUnhandled server exceptionnull
varies(custom)Business logic error via ItqanErrorPer-endpoint; documented in the endpoint's Reference page

validation_error Extra Shape

When error_name is validation_error, extra contains an array of field-level error objects:

{
"error_name": "validation_error",
"message": "Invalid Input",
"extra": [
{ "loc": ["query", "page"], "msg": "Input should be greater than or equal to 1", "type": "greater_than_equal" }
]
}

Client Handling

Branch on error_name. Do not branch on message (it changes with locale) or on HTTP status alone (multiple error names share the same status code).

async function apiFetch(url, options = {}) {
const resp = await fetch(url, options);
if (resp.ok) return resp.json();

const error = await resp.json();

switch (error.error_name) {
case "not_found":
// Resource doesn't exist — handle gracefully
return null;
case "validation_error":
// Show field errors to the user
throw new ValidationError(error.message, error.extra);
case "authentication_error":
case "token_not_valid":
// Redirect to login or refresh token
redirectToLogin();
return;
case "internal_error":
// Retry with exponential backoff
throw new RetryableError(error.message);
default:
// Unknown error — treat as internal
throw new Error(error.message);
}
}

Key Rules

  • Branch on error_name, not message or HTTP status.
  • Display message to users — it is already localized via Accept-Language.
  • Treat unknown error_name as internal_error — the API may add new error names; your client must not crash on them.
  • Retry with backoff on 5xx only — 4xx errors are client errors and won't resolve on retry.

Custom Endpoint Errors

Some endpoints raise ItqanError for business-logic conditions (for example, a conflict or a domain validation failure). These produce a custom error_name specific to that endpoint. Each endpoint's API Reference page documents the custom error names it can return.


See also: Design Principles · API Reference · Authentication