Back to Blogs
Web Development

Practical API Error Handling Patterns for Web and Mobile Clients

Learn concrete patterns for handling API errors in web and mobile applications, from consistent response formats to retry strategies and user‑friendly messaging.

Standardize Error Response Formats

Both web and mobile clients benefit from a predictable error payload. A common structure includes an HTTP status code, a machine‑readable error code, and a human‑readable message. For example, a JSON body might contain code, message, and an optional details object for field‑level validation problems. When every endpoint follows this contract, client code can centralize parsing logic instead of handling each endpoint separately.

Implement the format on the server side using the same schema for all frameworks you employ—whether it’s Django REST Framework, .NET Web API, or a Node.js/Express service. Consistency reduces the chance of missed edge cases and makes onboarding new developers faster.

Map HTTP Statuses to Business Logic

Do not rely on generic status codes alone. Align each status with a specific business scenario: 400 for validation failures, 401 for authentication issues, 403 for authorization problems, 404 for missing resources, and 429 for rate‑limit breaches. By documenting this mapping, front‑end teams can translate a 403 into a “You do not have permission to view this report” message, while a 429 becomes a “Please try again later” prompt.

When the mapping is explicit, you can create a shared error‑handling library that converts status codes into localized UI strings. This library lives in a single place for both React web apps and React Native mobile apps, ensuring the user experience stays consistent across platforms.

Implement Centralized Client Interceptors

Modern JavaScript stacks provide interceptor mechanisms—Axios interceptors, Fetch wrappers, or middleware in Redux‑Saga. Use these to catch errors globally, log them, and apply retry logic where appropriate. For mobile, libraries like Retrofit (Android) or Alamofire (iOS) offer similar hooks.

A typical interceptor flow is:

  • Check if the error is network‑related (e.g., timeout, DNS failure). If so, trigger an exponential back‑off retry up to a configurable limit.
  • If the status is 401, attempt token refresh using a stored refresh token, then replay the original request.
  • For 4xx and 5xx responses, extract the standardized error payload and forward it to the UI layer.

This pattern keeps individual request code clean and guarantees that every request benefits from the same resilience measures.

Use Idempotent Retries Wisely

Not every request should be retried automatically. Safe operations—GET, HEAD, and idempotent PUT/DELETE—can be retried without side effects. POST requests that create resources must be handled carefully to avoid duplicate records. One approach is to include a client‑generated idempotency key in the request header; the server stores the key and returns the original result if the same key is seen again.

For mobile apps operating on flaky networks, combine idempotency keys with a persistent retry queue. The queue survives app restarts, ensuring that a failed transaction eventually reaches the server without user intervention.

Provide User‑Friendly Feedback

Technical error details are valuable for developers but confusing for end users. Translate the message field from the API into concise UI text. Include context‑specific actions: a “Refresh” button for transient network errors, a “Contact support” link for 5xx server errors, or inline field highlights for validation failures.

When possible, surface error codes in logs or hidden debug panels. This gives support teams a quick reference without exposing internal codes to the user.

Log and Monitor Errors End‑to‑End

Instrument both client and server layers. On the client, send anonymized error events to a monitoring service (e.g., Azure Application Insights or Sentry). Include the endpoint, status code, error code, and user context (without personal data). On the server, log the full request and response payloads for any 4xx/5xx response, linking them to a correlation ID that the client also receives.

Correlating logs across the stack lets you spot patterns—such as a specific mobile OS version that triggers a 500 error—and address them before they affect more users.

Related reading: Practical Deployment Basics for Business Web Applications.