demo · v130

recovery strategy

The chromestatus motivation: "Without a specific error to distinguish such unrecoverable failures from transient failures, websites are forced to rely on heuristics to determine the appropriate response." Pick an error scenario below; the demo shows what your code would have done pre-Chrome 130 (one heuristic for all) versus what it can do now (a proper branch).

pre-Chrome 130 (generic UnknownError)

    Chrome 130+ (specific DOMException name)

      the code

      store.get("user-photo-2024").onerror = (ev) => {
        const err = ev.target.error;
      
        // pre-Chrome 130: err.name was "UnknownError" for both cases below.
        // Chrome 130+: the name tells you which recovery to use.
        switch (err.name) {
          case "NotReadableError":
            // Underlying file is gone. Backing store cannot recover. Re-fetch from
            // network, write a fresh copy, and surface a soft message to the user.
            log("permanent: file lost. re-downloading…");
            return refetchAndStore("user-photo-2024");
      
          case "QuotaExceededError":
            // Disk pressure. Evict old entries and retry once.
            log("transient: low disk. evicting cache…");
            return evictOldest().then(() => retry("user-photo-2024"));
      
          case "TimeoutError":
          case "TransactionInactiveError":
            // Truly transient. Exponential backoff.
            return backoffRetry("user-photo-2024");
      
          case "DataError":
          case "DataCloneError":
            // Schema mismatch. The value is there but unreadable in this build.
            // Migrate the row.
            return migrateRow("user-photo-2024");
      
          default:
            // Genuinely unknown — surface it.
            throw err;
        }
      };

      see also