Unhandled QuotaExceededError in CookieStore.persist() can crash request handling

Open Beginner friendly
#2,750 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
74/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
typescript
Domain
frontend

Research direction

Start in src/core/utils/cookieStore.ts:82-95 and trace the mentioned storeResponseCookies → handleRequest path. Reproduce a full localStorage condition, then verify persistence failures leave cookies available in memory, emit a console warning, and do not abort request handling.

Written by the indexing model from the issue text.

Description

Description

CookieStore.persist() calls localStorage.setItem() without a try/catch. If the storage quota is exceeded (common in long-running test suites or CI), the unhandled exception propagates up through storeResponseCookieshandleRequest, crashing the entire request handling pipeline.

Context

  • File: src/core/utils/cookieStore.ts:82-95
  • Component: Cookie persistence in browser environments

Current Behavior

private persist(): void {
  if (
    typeof localStorage === "undefined" ||
    typeof localStorage.setItem !== "function"
  ) {
    return
  }

  // ... build data array ...

  localStorage.setItem(this.#storageKey, JSON.stringify(data)) // Can throw QuotaExceededError
}

When localStorage is full, setItem throws a DOMException with QuotaExceededError. This is not caught, so it bubbles up through:

  1. cookieStore.setCookie() → calls this.persist()
  2. storeResponseCookies() → calls cookieStore.setCookie()
  3. handleRequest() → calls storeResponseCookies()

This means a full localStorage kills all subsequent request handling.

Expected Behavior

Cookie persistence failure should be graceful — cookies should still work in-memory for the current session, and a console warning should be emitted.

Suggested Fix

  private persist(): void {
    if (
      typeof localStorage === "undefined" ||
      typeof localStorage.setItem !== "function"
    ) {
      return
    }

    const data: Array<SerializedCookie> = []
    const { idx } = this.#memoryStore

    for (const domain in idx) {
      for (const path in idx[domain]) {
        for (const key in idx[domain][path]) {
          data.push(idx[domain][path][key].toJSON())
        }
      }
    }

-   localStorage.setItem(this.#storageKey, JSON.stringify(data))
+   try {
+     localStorage.setItem(this.#storageKey, JSON.stringify(data))
+   } catch (error) {
+     // Gracefully handle storage quota errors.
+     // Cookies remain available in-memory for this session.
+     console.warn(
+       \`[msw] Failed to persist cookies to localStorage: \${error}\`
+     )
+   }
  }

Impact

  • Severity: Medium — Affects long-running browser test suites where localStorage fills up over many test runs
  • Current workaround: manually clear localStorage between tests, but this defeats the purpose of cookie persistence

Environment

  • Browser environments with limited localStorage (~5MB)
  • Long-running test suites with many cookie-heavy scenarios

Positively — happy to submit a PR if this is welcome.

Dominant language
TypeScript
Stars
18.2k
Forks
626
Avg merge
2h 10m
Merged PRs (30d)
11

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from mswjs/msw

All issues in mswjs/msw

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.