# Network errors, empty states, and edge cases show user-friendly messages

- **Pattern:** `ab-000495` (`app-store-review-blockers.completeness-stability.error-states-handled`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000495
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000495)

## Why it matters

Reviewers deliberately test on degraded networks and with edge-case data. Empty `catch` blocks (CWE-390) that swallow errors produce blank white screens — a visible failure that signals low quality and triggers rejection under Apple's guideline 2.1. ISO 25010:2011 fault-tolerance requires systems to continue operating under abnormal conditions. Beyond rejection risk, raw error messages (`{error.message}`) leak implementation details and destroy user trust. A screen that shows nothing when the network is bad is indistinguishable from a bug.

## Severity rationale

High because empty catch blocks and missing error states produce blank screens that reviewers directly observe, causing rejection under guideline 2.1.

## Remediation

Implement all four UI states for every data-fetching screen.

```tsx
// src/screens/FeedScreen.tsx
export default function FeedScreen() {
  const { data, isLoading, error, refetch } = useFeed();

  if (isLoading) return <ActivityIndicator />;
  if (error) return (
    <View style={styles.center}>
      <Text>Couldn't load your feed.</Text>
      <Button title="Try again" onPress={refetch} />
    </View>
  );
  if (!data?.length) return <EmptyState message="Nothing here yet — check back soon." />;
  return <FlatList data={data} renderItem={renderItem} />;
}
```

Never render `{error.message}` or `{error.toString()}` directly. Test every screen with airplane mode enabled on the simulator before submission.

## Detection

- **ID:** `error-states-handled`
- **Severity:** `high`
- **What to look for:** Count all relevant instances and enumerate each. Search for `catch` blocks that are empty or only call `console.log()`. Look for screens that fetch data but have no empty-state UI (no results, no content). Check for raw error objects being rendered to the user: `{error.message}`, `{err.toString()}`, JSON-stringified objects displayed in the UI. Look for `undefined` or `null` rendered where JSX expects a string. Also look for "Something went wrong" text with no actionable retry option. In Flutter, check `FutureBuilder` and `StreamBuilder` for missing `snapshot.hasError` and `snapshot.connectionState == ConnectionState.none` handling.
- **Pass criteria:** All data-fetching screens have: a loading state, a non-empty content state, an error state with a user-friendly message and retry option, and an empty state (if the data set can be empty). At least 1 implementation must be verified.
- **Fail criteria:** Empty `catch` blocks that swallow errors silently; raw error messages or stack traces visible in the UI; screens that show a blank white area when data fails to load; no retry mechanism after network errors.
- **Skip (N/A) when:** Never.
- **Detail on fail:** `"ProfileScreen catch block only calls console.log — network errors show a blank screen"` or `"FeedScreen has no empty-state UI — new users see a completely blank feed with no guidance"`
- **Remediation:** Reviewers test on real networks (sometimes deliberately bad ones) and with edge-case data.
  1. For every data-fetching screen, implement all four states:
     ```tsx
     if (isLoading) return <LoadingSpinner />;
     if (error) return <ErrorView message="Couldn't load data" onRetry={refetch} />;
     if (!data?.length) return <EmptyState message="Nothing here yet" />;
     return <DataList data={data} />;
     ```
  2. Never render `{error.message}` or `{error.toString()}` directly — show a friendly message instead
  3. Add a retry button to all error states
  4. Test by disabling network access on the simulator/device and navigating through the app

## External references

- cwe CWE-390
- iso-25010 fault-tolerance

Taxons: error-resilience, user-experience

HTML version: https://auditbuffet.com/patterns/ab-000495
