Skip to content

fix: prevent storage quota errors during event logging#1286

Closed
mattbodle wants to merge 3 commits into
mParticle:developmentfrom
mattbodle:fix/storage-quota-event-logging
Closed

fix: prevent storage quota errors during event logging#1286
mattbodle wants to merge 3 commits into
mParticle:developmentfrom
mattbodle:fix/storage-quota-event-logging

Conversation

@mattbodle

Copy link
Copy Markdown
Contributor

Background

  • Partner error logs showed QuotaExceededError surfacing from the synchronous commerce event path, including eCommerce.logImpression.
  • The SDK had unguarded Web Storage writes in persistence and vault storage paths, so localStorage/sessionStorage quota or blocked-storage failures could escape event logging.

What Has Changed

  • Makes vault storage best-effort by catching Web Storage read/write/remove failures and returning a boolean write result.
  • Guards savePersistence() localStorage writes so quota failures are logged without throwing.
  • Adds offline batch queue trimming that drops oldest batches until localStorage accepts the payload, while retaining batches in memory if storage is fully unavailable.
  • Adds regression tests for vault write failures, persistence write failures, and offline batch trimming behavior.
  • Rebuilds dist/mparticle.js.

Verification

  • npm run build:iife
  • npm run build:test-bundle
  • npm run test:jest
  • npx karma start test/karma.config.js --browsers ChromeHeadless --single-run

Screenshots/Video

  • N/A

Checklist

  • Self-review completed
  • Tests added or updated
  • Tested locally

@mattbodle mattbodle requested a review from a team as a code owner June 26, 2026 10:27
@cursor

cursor Bot commented Jun 26, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes core offline batch and persistence write paths; quota recovery intentionally drops oldest queued batches, which is a deliberate data-loss tradeoff under storage pressure.

Overview
Stops Web Storage failures (quota exceeded, blocked storage, corrupt reads) from throwing into synchronous event/commerce logging paths.

Vault layer now treats reads/writes as best-effort: store() returns a StorageResult (Success / QuotaExceeded / Unavailable), and retrieve() / purge() swallow parse and access errors instead of propagating them.

Offline batch persistence routes queue saves through storeBatchesQueuedForProcessing(), which drops the oldest batches until localStorage accepts the payload when quota is exceeded, logs a warning, and keeps batches in memory (no trimming) when storage is unavailable. prepareAndUpload also guards retrieve() ?? [] so null/corrupt offline data does not break the upload loop.

Persistence wraps savePersistence localStorage setItem in try/catch and logs without throwing.

Regression tests cover vault outcomes, persistence save failures, batch trimming, unavailable storage, and null retrieve during upload.

Reviewed by Cursor Bugbot for commit fdbe5d6. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread src/batchUploader.ts Outdated
@khushi1033 khushi1033 changed the base branch from master to development June 26, 2026 14:49

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fdbe5d6. Configure here.

Comment thread src/batchUploader.ts
if (isEmpty(batches)) {
this.batchVault.store([]);
this.batchesQueuedForProcessing = [];
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failed offline clears duplicate events

High Severity

After batches or session events are uploaded, the SDK clears offline vaults via purge() and store([]), but those calls now swallow storage errors and callers ignore failure results. If local or session storage is not actually cleared, the next prepareAndUpload reloads the same payloads and can send duplicate analytics events.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fdbe5d6. Configure here.

Comment thread src/batchUploader.ts
// Could not persist any batches; retain them in memory to retry later.
this.mpInstance.Logger.warning(
'Offline batch storage is unavailable. Retaining batches in memory.'
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong warning after quota trim fails

Low Severity

When every batchVault.store attempt returns QuotaExceeded after trimming down to a single batch, the loop exits without hitting the Unavailable branch, but the code still logs that offline batch storage is unavailable. That mislabels a pure quota problem and can mislead monitoring or debugging.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fdbe5d6. Configure here.

@khushi1033

Copy link
Copy Markdown
Contributor

Closing in favor of #1287

@khushi1033 khushi1033 closed this Jun 26, 2026
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
12.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants