How to Simulate API Errors and Edge Cases in Frontend Development

Real APIs don't always return 200. Learn how to simulate 400, 401, 404, 500 errors and empty states in your frontend so your app handles failure gracefully before it ships.

How to Simulate API Errors and Edge Cases in Frontend Development

A frontend that only works when everything goes right is a frontend that will embarrass you in production. Real APIs fail. They time out. They return empty lists. They send back a 401 when a session expires. If you haven't tested these scenarios before shipping, your users will discover them for you.

The problem is that these failure states are hard to trigger against a real backend. You can't easily make a live API return a 500 on demand. That's exactly where mock APIs shine.

Why You Must Test Error States

Consider what happens in your app when:

  • The login API returns a 401 Unauthorized — does your app redirect to login, or does it crash silently?
  • A search returns an empty array — do you show a helpful "No results" message or a blank white screen?
  • A payment endpoint returns 500 Internal Server Error — do you show a retry button or leave the user staring at a spinner forever?
  • An API takes 8 seconds to respond — does your loading state still look good?

If you've never tested these, you don't know. And your users will find out at the worst possible time.

Setting Up Error Mocks

With a mock API tool, you create separate endpoints for each scenario you want to test. You're not limited to one response per route — you can create multiple mocks with different configurations and switch between them during development.

Simulating a 401 Unauthorized

Create a mock endpoint at GET /api/me with:

  • Status code: 401
  • Response body:
{
  "error": "Unauthorized",
  "message": "Your session has expired. Please log in again."
}

Now point your app at this mock and verify your auth guard handles it correctly — redirecting to the login page, clearing the local token, showing the right message.

Simulating a 404 Not Found

{
  "error": "Not Found",
  "message": "The requested resource does not exist.",
  "code": 404
}

Test that your UI shows a graceful "not found" state rather than an unhandled exception.

Simulating a 500 Server Error

{
  "error": "Internal Server Error",
  "message": "Something went wrong on our end. Please try again later."
}

This is the most important one. Your app should never show a raw error object or a blank screen when the server crashes.

Simulating a Validation Error (422)

{
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email field is required."],
    "password": ["The password must be at least 8 characters."]
  }
}

Test that your form correctly maps field-level errors back to the right input fields and highlights them.

Simulating Empty States

Empty arrays are not errors, but they need just as much attention. Create a mock that returns:

{
  "data": [],
  "total": 0,
  "page": 1,
  "per_page": 20
}

Render your list component against this response. You should see a clear "No items yet" state — not a broken layout or invisible content.

Simulating Slow APIs with Response Delays

Network latency is invisible during local development because everything runs on localhost. This creates a false sense of performance. A real user on a mobile connection might wait 3–5 seconds for a response.

Most mock API tools let you add a delay to any endpoint — for example, 3000ms. Use this to:

  • Verify your loading spinners and skeleton screens actually appear
  • Catch UI elements that become interactive before data has loaded
  • Test whether button double-clicks are properly debounced during slow requests
  • Confirm your app doesn't hang indefinitely — implement a timeout and test it

Simulating Partial Data

What if the API returns a user object but some optional fields are null or missing?

{
  "id": 42,
  "name": "Jordan Lee",
  "email": "jordan@example.com",
  "avatar": null,
  "bio": null,
  "phone": null
}

Your UI must handle nullable fields gracefully. Test that avatar placeholders show, that null bio sections collapse cleanly, and that you're not calling .length on a null field somewhere.

A Testing Checklist

For every API-dependent feature, run through this checklist before marking it done:

  • ✅ Happy path — data loads and renders correctly
  • ✅ Empty state — empty array or no data shows a helpful message
  • ✅ Loading state — spinner/skeleton appears while waiting
  • ✅ 401 — app redirects or prompts re-authentication
  • ✅ 404 — app shows a not-found state, doesn't crash
  • ✅ 500 — app shows an error message with retry option
  • ✅ Slow response (3s+) — loading state persists correctly
  • ✅ Null/missing fields — no crashes from undefined property access

Using MockServer for Error Testing

MockServer lets you create separate mock endpoints for each error scenario in seconds. You can configure the exact status code, response body, and delay — then share the mock URL with your teammates so everyone is testing against the same scenarios. When the real backend is ready, you swap the URL and you're done.

Conclusion

Error handling is not an afterthought — it's part of the feature. Testing it requires being able to trigger errors on demand, which a real backend rarely lets you do easily. Mock APIs give you full control over every response your frontend might receive, so you can build UIs that behave gracefully under any condition.