Back to blog
5 min readShadab

Make 401 and 500 Boring: One-Click Error State Testing with Mockfill

How to systematically test 401, 403, 404, 429, and 500 paths in your frontend without begging the backend team to break staging.

Make 401 and 500 Boring: One-Click Error State Testing with Mockfill header image
Mock APIError HandlingQA Workflow

Most frontends have a confident happy path and a fragile everything else. The 401 retry loop has never been seen by the dev who wrote it. The 500 toast renders raw HTML. The 429 case throws an unhandled promise. None of these are caught in review because none of them are easy to trigger.

The reason error handling rots is structural: forcing a real backend to return a 500 on demand is annoying, and forcing it to return a specific 500 with a specific body is annoying enough that nobody does it twice. Mockfill removes that friction entirely.

Nano Banana prompt: "UI mockup of a web app dashboard with an error toast in the top right corner. The toast contains raw, leaked stack trace text like 'NullPointerException at UserController.java:142'. A bold red highlight box and arrow point at the toast. Caption strip: 'What happens when the 500 path is never tested.' Light theme, modern flat design, indigo accents, sharp readable typography."

The pattern: one endpoint, many rules

For every endpoint that matters, create a small family of rules — one per status code you care about — pointing at the same URL. Mockfill matches by method + URL pattern with first-match-wins ordering, so you enable exactly one at a time.

A typical family for GET /api/users/:id:

Rule name Status Body
users_200_happy 200 Realistic user object
users_200_empty 200 {} or null fields
users_401_expired 401 { "error": "AUTH_EXPIRED" }
users_403_forbidden 403 { "error": "FORBIDDEN" }
users_404_missing 404 { "error": "NOT_FOUND" }
users_429_throttled 429 { "error": "RATE_LIMITED" } with retry-after header
users_500_unknown 500 Realistic server error body

Nano Banana prompt: "UI mockup of a Mockfill rules list panel, light theme. Seven stacked rule cards each labeled 'users_200_happy', 'users_200_empty', 'users_401_expired', 'users_403_forbidden', 'users_404_missing', 'users_429_throttled', 'users_500_unknown'. Each row shows a method tag (GET), a URL '/api/users/:id', and a toggle switch on the right. Status codes are color-coded badges. Caption: 'One endpoint, seven testable realities.' Modern flat SaaS design, indigo accents."

Group them into presets

Individual rules are not the unit of work — scenarios are. Mockfill presets let you flip a whole set of rules at once. Build presets that match the user-visible scenarios you care about:

  • Happy path — all 200s
  • Auth failure — every protected endpoint returns 401
  • Server outage — every endpoint returns 500
  • Throttled — every endpoint returns 429 with retry-after: 5
  • Half outage — read endpoints return 200, write endpoints return 503

A preset is a one-click context switch. QA can run the entire flow under "Auth failure" in 30 seconds, then switch to "Throttled" and run it again.

A realistic 401 body

{
  "error": {
    "code": "AUTH_EXPIRED",
    "message": "Your session has expired. Please sign in again."
  }
}

A realistic 429 with the right header:

{
  "status": 429,
  "headers": { "retry-after": "5" },
  "body": { "error": "RATE_LIMITED" }
}

The value is in the specificity. Mocking a generic 500 with {} does not catch the bug where your error toast tries to render error.message and crashes on undefined. Mocking the exact body shape your backend returns does.

Nano Banana prompt: "Two side-by-side UI mockups of an error toast notification. Left toast displays the literal text 'undefined' with a red broken-icon. Right toast displays a polished message 'Your session has expired. Please sign in again.' with a key icon. Caption strip: 'Same code, different mock body.' Light theme, indigo accents, modern flat design, crisp readable typography."

What to actually verify in each scenario

For each preset, walk the UI and answer:

  • 401: Does the app redirect to login? Does it preserve the in-progress form state? Does it clear cached user data?
  • 403: Is the messaging distinguishable from "not found" without leaking object existence?
  • 404: Does the empty state look intentional or broken?
  • 429: Does the UI surface retry-after, or does it spam retries?
  • 500: Is the error message generic enough that it does not leak internals (stack traces, file paths, framework names)?

The 500 check is also a small but real security check. Improper error handling that leaks server internals is a recognized OWASP issue, and the cheapest way to catch it is to mock a verbose error and look at what your UI actually renders.

Sharing with QA

Export the rule set as JSON, commit it to your repo, and write a one-paragraph README:

repo/
  tools/
    mockfill/
      error-states.json
      README.md

Now QA does not need a backend dev to "make staging return a 500." They import the JSON, pick a preset, and run the test. The back-and-forth disappears.

Nano Banana prompt: "UI mockup of a dropdown menu inside a Mockfill extension panel. The dropdown is open and shows five preset options stacked: 'Happy path', 'Auth failure', 'Server outage', 'Throttled', 'Half outage'. Each option has a small colored status icon. Caption: 'QA's regression menu.' Light theme, modern flat SaaS design, indigo highlights, soft drop shadow on the dropdown."

Graduating to automation

Once a scenario catches a real bug, it deserves to be enforced in CI. Port the same response body and status into a Cypress cy.intercept or a Playwright route.fulfill. The mock you used to find the bug becomes the mock that prevents it from coming back.

The takeaway

Error handling rots when it is hard to test. Mockfill makes it cheap. Build the rule family once, build the presets once, share the JSON, and the 500 path stops being scary.

Keep reading

Related technical articles

QA Presets That Actually Stick: Deterministic Regression Testing with Mockfill cover image
5 min read
Mock APIQA WorkflowRegression Testing

QA Presets That Actually Stick: Deterministic Regression Testing with Mockfill

Build a shareable QA preset library that survives staging outages, environment drift, and 'works on my machine' regression runs.

Read article
Copy as cURL, Paste, Repro: The Fastest Debug Loop Using Mockfill cover image
5 min read
Mock APIDebuggingBug Reproduction

Copy as cURL, Paste, Repro: The Fastest Debug Loop Using Mockfill

Turn 'I can't reproduce it locally' into a deterministic, reloadable bug reproduction in under five minutes by importing the failing request as cURL into Mockfill.

Read article
Demo Mode Without Backend Drama: Deterministic Flows with Mockfill cover image
5 min read
Mock APIProduct DemosSales Engineering

Demo Mode Without Backend Drama: Deterministic Flows with Mockfill

Run product demos and stakeholder reviews against deterministic API responses so staging outages and inconsistent data never derail a presentation again.

Read article