Consequences of Not Normalizing Errors
This section shows real problems that happen when errors aren't normalized properly. Understanding these helps you avoid production issues.
Problem 1: Wrong Status Codes
What happens
Your product detail page calls middleware to fetch a product. The product doesn't exist. Without proper normalization:
- External API throws →
AxiosErrorwith nestedresponse.status = 404 - Middleware can't extract status → Defaults to 500 Internal Server Error
- Frontend receives 500 → Shows "Something went wrong with our server"
- User thinks the site is broken → Actually, the product just doesn't exist
Impact: Users see generic error messages. Support team gets confused tickets. Logs show 500s for normal "not found" cases.
The fix
Configure your HTTP client with an error adapter:
// In index.server.ts - one-time setup
const client = adapter.withErrorNormalizer(httpClient);
// In endpoint - clean code
try {
const response = await client.get(`/products/${id}`);
return response.data;
} catch (error) {
// Error already normalized by adapter (proper 404)
throw error;
}
Result: Frontend gets 404, shows "Product not found", user understands the situation.
Problem 2: Circuit Breaker False Positives
What happens
This is the most serious consequence. Here's the chain reaction:
- User searches for invalid product IDs (typos, old SKUs, etc.)
- API returns 404 Not Found — normal business error
- Error escapes unnormalized — no status code attached
- Circuit breaker sees "unknown error" — treats it as infrastructure failure
- After 5-10 failed requests — circuit breaker opens
- All subsequent requests fail — even for valid products
- Your entire product catalog becomes unavailable
Impact: System outage caused by normal business errors. Valid requests fail. Revenue loss. Emergency fix required.
Why this happens
The circuit breaker distinguishes between:
- 4xx errors (business errors) → Don't count toward failure threshold
- 5xx errors (infrastructure failures) → Count toward opening circuit
- No status code (unnormalized errors) → Treated as infrastructure failure
A few invalid product searches shouldn't break your entire catalog. But without normalization, that's exactly what happens.
The fix
Configure HTTP clients with error adapters:
// In index.server.ts
const externalApi = adapter.withErrorNormalizer(httpClient);
// In endpoint
try {
const { data } = await externalApi.getProduct(id);
return data;
} catch (error) {
// Adapter normalized the error
// 404 → Business error → Circuit stays closed
// 503 → Infrastructure error → Counts toward circuit opening
throw error;
}
Result: 404s don't trigger circuit breaker. System stays available. Only real infrastructure failures open the circuit.
Problem 3: Frontend Can't Handle Errors
What happens
Your "Add to Cart" button should show different messages based on what went wrong:
- Product out of stock → "This item is currently unavailable"
- Product discontinued → "This product is no longer sold"
- Cart service down → "Unable to add item, please try again"
Without structured error data, frontend gets generic errors and can only show "Something went wrong".
Impact: Poor user experience. Users don't know if they should try again, search for alternatives, or contact support.
The fix
Include structured data in your errors:
if (data?.modifications?.find(m => m.statusCode === 'noStock')) {
throw context.createHttpError({
statusCode: 409,
message: 'Product is out of stock',
data: {
errors: [{ type: 'InsufficientStockError' }],
productSku: args.sku,
},
});
}
Frontend can now check error.data.errors[0].type === 'InsufficientStockError' and show a specific message with a "Notify me when available" button.
Real-World Example
The Scenario
E-commerce site selling electronics. Customer searches for old laptop model (discontinued last year).
Without Normalization
// Middleware - no error adapter configured
const { data } = await externalApi.getProduct(sku); // Throws 404
// Circuit breaker sees: Unknown error (no status)
// After 10 searches for old models: Circuit opens
// Impact: All product pages return 503 Service Unavailable
// Duration: Until someone manually resets circuit or timeout expires
Outcome:
- 🔴 Entire catalog unavailable for 30 seconds
- 🔴 Orders drop to zero during downtime
- 🔴 On-call engineer paged at 3 AM
- 🔴 Post-mortem reveals "404s triggered circuit breaker"
With Normalization
// Middleware - adapter configured in client setup
try {
const { data } = await externalApi.getProduct(sku);
return data;
} catch (error) {
// Adapter already normalized the error
throw error; // Proper 404 Not Found (business error)
}
// Circuit breaker sees: 404 Not Found (business error)
// Circuit stays closed
// User sees: "Product not found" with suggestions
Outcome:
- ✅ Circuit breaker ignores 404s
- ✅ Valid products load normally
- ✅ User gets helpful message
- ✅ No outage, no page, no post-mortem
Summary Table
| Without Normalization | With Normalization |
|---|---|
| Frontend shows "Error 500" | Frontend shows "Product not found" |
| Circuit breaker opens on 404s | Circuit breaker ignores 404s |
| Generic error messages | Specific, actionable messages |
| Support team confused | Support team sees clear error types |
| Logs full of "Unknown errors" | Logs show proper status codes |
| On-call pages at night | Smooth operation |
Key Takeaway
Error normalization isn't just about "clean code" — it's about system reliability and user experience. Ten minutes writing proper error handling saves hours of debugging production outages.