0

I've been googling some time now and could not find a way to catch the exception of the browser's Failed to execute 'setItem' on 'Storage': Setting the value of '[my state]' exceeded the quota error.

Easily testable by using this little script (remove the localStorage.removeItem('test'); to keep the data) and then just run your ngrx angular app which adds some data to the store.

I did found ways to calculate the used space, but since that is browser dependent and the quota might change in the future, we would like to have a fallback when s**t hits the fan.

After the reducer returns the new set of changes, it is somewhere internally setting the data in the store, but unfortunately as far as I can see there is no way to catch that error.

I've tried to add a try-catch around the return block inside the reducer, that didn't help.

The browser does leave you with a stacktrace:

ERROR Error: Failed to execute 'setItem' on 'Storage': Setting the value of 'Inspections' exceeded the quota. at https://localhost:4200/vendor.js:110584:35 at Array.forEach () at stateSync (https://localhost:4200/vendor.js:110564:10) at https://localhost:4200/vendor.js:110654:89 at https://localhost:4200/vendor.js:114084:20 at computeNextEntry (https://localhost:4200/vendor.js:112837:21) at recomputeStates (https://localhost:4200/vendor.js:112890:15) at https://localhost:4200/vendor.js:113238:26 at ScanSubscriber.StoreDevtools.liftedAction$.pipe.Object.state [as accumulator] (https://localhost:4200/vendor.js:113291:38) at ScanSubscriber._tryNext (https://localhost:4200/vendor.js:201979:27) at ScanSubscriber._next (https://localhost:4200/vendor.js:201972:25) at ScanSubscriber.next (https://localhost:4200/vendor.js:196049:18) at WithLatestFromSubscriber._next (https://localhost:4200/vendor.js:204041:34) at WithLatestFromSubscriber.next (https://localhost:4200/vendor.js:196049:18) at Notification.observe (https://localhost:4200/vendor.js:195388:50)

There is some clue here that there should be a storageError function that can be provided?

({ stateKey, excludeKeys, storageKeySerializerForFeature, serialize, storageForFeature }) => {
        /** @type {?} */
        const featureState = Object(lodash_es__WEBPACK_IMPORTED_MODULE_0__["cloneDeep"])(state[stateKey]);
        /** @type {?} */
        const filteredState = cleanState(excludeKeysFromState(featureState, excludeKeys));
        if (Object(lodash_es__WEBPACK_IMPORTED_MODULE_0__["isPlainObject"])(filteredState) && !Object.keys(filteredState).length) {
            return;
        }
        /** @type {?} */
        const key = storageKeySerializerForFeature
            ? storageKeySerializerForFeature(stateKey)
            : storageKeySerializer(stateKey);
        /** @type {?} */
        const value = serialize ? serialize(filteredState) : JSON.stringify(filteredState);
        try {
            if (storageForFeature) {
                storageForFeature.setItem(key, value);
            }
            else {
                storage.setItem(key, value);
            }
        }
        catch (e) {
            if (storageError) {
                storageError(e);
            }
            else {
                throw e;
            }
        }
    }));
    return state;

When a solution is found, this answer can be used to deal with the exception itself for different browsers.

CularBytes
  • 8,367
  • 6
  • 65
  • 94

0 Answers0