Back to Blogs
Web Development

Practical API Error Handling Patterns for Web and Mobile Clients

Learn concrete patterns for detecting, classifying, and responding to API errors in JavaScript, Django, and .NET backends, helping your web and mobile teams deliver reliable user experiences.

Classify Errors at the Source

Before you can handle an error, you need to know what kind of error you are dealing with. A pragmatic classification separates three domains: network failures (timeouts, DNS issues), transport errors (HTTP status codes outside the 2xx range), and business‑logic failures (validation errors, quota limits, domain‑specific rules). By mapping each response to one of these buckets early in the client code, you avoid tangled conditional logic later.

Implement a small utility that inspects the HTTP response and returns a normalized error object. In JavaScript you might use fetch and examine response.ok for transport errors, while catching exceptions for network problems. On the server side, Django’s Response class and .NET’s HttpResponseMessage provide similar hooks to emit a consistent JSON payload with an errorCode and message field for business errors.

Use a Centralized Error Handler

Both web and mobile clients benefit from a single place where all API errors are processed. For a single‑page application built with JavaScript, create an interceptor (Axios interceptors or a fetch wrapper) that receives every response, runs the classification logic, and then routes the error to the appropriate UI layer. Mobile SDKs in Swift or Kotlin can adopt a similar pattern with a network layer that returns a Result type.

Centralizing error handling gives you three practical advantages: consistent logging, uniform user messaging, and the ability to trigger global actions such as token refresh or forced logout when authentication errors (e.g., 401) occur.

Implement Retry and Back‑off Strategies

Transient network glitches are common on mobile networks and can also affect web users on flaky connections. A simple exponential back‑off algorithm—retry after 1 second, then 2 seconds, then 4 seconds—reduces the chance of overwhelming the server while still giving the request a chance to succeed. Limit retries to a small count (usually 3) and surface a clear message if all attempts fail.

When retrying, be careful to avoid duplicate side effects. Idempotent endpoints (GET, DELETE) are safe to retry; for POST or PATCH you should include an idempotency key in the request header so the backend can detect and ignore duplicates. This pattern is supported out‑of‑the‑box by many .NET and Django frameworks.

Provide User‑Friendly Feedback

Technical error codes are useful for developers, but end users need actionable messages. Map each error bucket to a UI pattern: network errors show a “Retry” button, validation errors highlight the offending fields, and business rule violations display a concise explanation (e.g., “You have exceeded your monthly quota”). Keep the language neutral and avoid exposing internal stack traces.

For mobile apps, consider using native toast or snackbar components that disappear after a few seconds, reserving modal dialogs for critical failures such as authentication loss. On the web, inline alerts near the affected form field improve discoverability and reduce user frustration.

Log and Monitor Errors Systematically

Even with robust client‑side handling, you need visibility into error trends. Send normalized error objects to a logging service (e.g., Azure Application Insights, AWS CloudWatch, or an open‑source ELK stack). Include context such as endpoint name, user identifier (hashed for privacy), and the classification bucket. Over time you can set alerts for spikes in 5xx responses or repeated business‑logic failures, enabling proactive fixes before users notice.

On the client side, capture unhandled promise rejections and uncaught exceptions, and forward them to the same logging pipeline. This unified view helps technical decision‑makers prioritize reliability investments across both web and mobile platforms.

Related reading: Practical Language Choices for Teams Managing Web and Mobile Backends.