Skip to content

Commit d2ac3b0

Browse files
Wrap error
1 parent b799fcd commit d2ac3b0

File tree

6 files changed

+35
-24
lines changed

6 files changed

+35
-24
lines changed

packages/firestore/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
"test:all": "run-p test:browser test:travis test:minified",
2121
"test:browser": "karma start --single-run",
2222
"test:browser:debug": "karma start --browsers=Chrome --auto-watch",
23-
"test:node": "FIRESTORE_EMULATOR_PORT=8080 FIRESTORE_EMULATOR_PROJECT_ID=test-emulator TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --file index.node.ts --file test/util/node_persistence.ts --opts ../../config/mocha.node.opts",
24-
"test:node:prod": "TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --file index.node.ts --file test/util/node_persistence.ts --opts ../../config/mocha.node.opts",
23+
"test:node": "FIRESTORE_EMULATOR_PORT=8080 FIRESTORE_EMULATOR_PROJECT_ID=test-emulator TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --file index.node.ts --opts ../../config/mocha.node.opts",
24+
"test:node:prod": "TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --file index.node.ts --opts ../../config/mocha.node.opts",
2525
"test:node:persistence": "FIRESTORE_EMULATOR_PORT=8080 FIRESTORE_EMULATOR_PROJECT_ID=test-emulator USE_MOCK_PERSISTENCE=YES TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --require ts-node/register --require index.node.ts --require test/util/node_persistence.ts --opts ../../config/mocha.node.opts",
2626
"test:node:persistence:prod": "USE_MOCK_PERSISTENCE=YES TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --require ts-node/register --require index.node.ts --require test/util/node_persistence.ts --opts ../../config/mocha.node.opts",
2727
"test:travis": "ts-node --compiler-options='{\"module\":\"commonjs\"}' ../../scripts/emulator-testing/firestore-test-runner.ts",

packages/firestore/src/local/simple_db.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,18 @@ export interface IterateOptions {
406406
reverse?: boolean;
407407
}
408408

409+
/** An error that wraps exceptions that thrown during IndexedDB execution. */
410+
export class IndexedDbTransactionError extends FirestoreError {
411+
name = 'IndexedDbTransactionError';
412+
413+
constructor(cause: Error) {
414+
super(
415+
Code.UNKNOWN,
416+
'IndexedDB transaction failed with environment error: ' + cause
417+
);
418+
}
419+
}
420+
409421
/**
410422
* Wraps an IDBTransaction and exposes a store() method to get a handle to a
411423
* specific object store.
@@ -432,7 +444,9 @@ export class SimpleDbTransaction {
432444
};
433445
this.transaction.onabort = () => {
434446
if (transaction.error) {
435-
this.completionDeferred.reject(transaction.error);
447+
this.completionDeferred.reject(
448+
new IndexedDbTransactionError(transaction.error)
449+
);
436450
} else {
437451
this.completionDeferred.resolve();
438452
}
@@ -441,7 +455,7 @@ export class SimpleDbTransaction {
441455
const error = checkForAndReportiOSError(
442456
(event.target as IDBRequest).error!
443457
);
444-
this.completionDeferred.reject(error);
458+
this.completionDeferred.reject(new IndexedDbTransactionError(error));
445459
};
446460
}
447461

packages/firestore/src/util/async_queue.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { logDebug, logError } from './log';
2121
import { CancelablePromise, Deferred } from './promise';
2222
import { ExponentialBackoff } from '../remote/backoff';
2323
import { PlatformSupport } from '../platform/platform';
24+
import { IndexedDbTransactionError } from '../local/simple_db';
2425

2526
const LOG_TAG = 'AsyncQueue';
2627

@@ -319,7 +320,7 @@ export class AsyncQueue {
319320
* Enqueue a retryable operation.
320321
*
321322
* A retryable operation is rescheduled with backoff if it fails with a
322-
* DOMException or a DOMError (the error types used by IndexedDB). All
323+
* SimpleDbTransactionError (the error type used by SimpleDb). All
323324
* retryable operations are executed in order and only run if all prior
324325
* operations were retried successfully.
325326
*/
@@ -338,13 +339,7 @@ export class AsyncQueue {
338339
deferred.resolve();
339340
this.backoff.reset();
340341
} catch (e) {
341-
// We only retry errors that match the ones thrown by IndexedDB (see
342-
// https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction/error)
343-
if (
344-
(typeof DOMException !== 'undefined' &&
345-
e instanceof DOMException) ||
346-
(typeof DOMError !== 'undefined' && e instanceof DOMError)
347-
) {
342+
if (e.name === 'IndexedDbTransactionError') {
348343
logDebug(LOG_TAG, 'Operation failed with retryable error: ' + e);
349344
this.backoff.backoffAndRun(retryingOp);
350345
} else {

packages/firestore/test/unit/specs/spec_test_components.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { TargetCache } from '../../../src/local/target_cache';
3535
import { RemoteDocumentCache } from '../../../src/local/remote_document_cache';
3636
import { IndexManager } from '../../../src/local/index_manager';
3737
import { PersistencePromise } from '../../../src/local/persistence_promise';
38+
import { IndexedDbTransactionError } from '../../../src/local/simple_db';
3839
import { debugAssert } from '../../../src/util/assert';
3940
import {
4041
MemoryEagerDelegate,
@@ -113,7 +114,9 @@ export class MockPersistence implements Persistence {
113114
) => PersistencePromise<T>
114115
): Promise<T> {
115116
if (this.injectFailures) {
116-
return Promise.reject(new DOMException('Simulated retryable error'));
117+
return Promise.reject(
118+
new IndexedDbTransactionError(new Error('Simulated retryable error'))
119+
);
117120
} else {
118121
return this.delegate.runTransaction(action, mode, transactionOperation);
119122
}

packages/firestore/test/unit/util/async_queue.test.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { Code } from '../../../src/util/error';
2323
import { getLogLevel, setLogLevel, LogLevel } from '../../../src/util/log';
2424
import { Deferred, Rejecter, Resolver } from '../../../src/util/promise';
2525
import { fail } from '../../../src/util/assert';
26+
import { IndexedDbTransactionError } from '../../../src/local/simple_db';
2627

2728
use(chaiAsPromised);
2829

@@ -217,7 +218,9 @@ describe('AsyncQueue', () => {
217218
queue.enqueueRetryable(async () => {
218219
doStep(1);
219220
if (completedSteps.length === 1) {
220-
throw new DOMException('Simulated retryable error');
221+
throw new IndexedDbTransactionError(
222+
new Error('Simulated retryable error')
223+
);
221224
}
222225
});
223226
await queue.runDelayedOperationsEarly(TimerId.AsyncQueueRetry);
@@ -265,7 +268,9 @@ describe('AsyncQueue', () => {
265268
queue.enqueueRetryable(async () => {
266269
doStep(1);
267270
if (completedSteps.length === 1) {
268-
throw new DOMException('Simulated retryable error');
271+
throw new IndexedDbTransactionError(
272+
new Error('Simulated retryable error')
273+
);
269274
}
270275
});
271276

@@ -291,7 +296,9 @@ describe('AsyncQueue', () => {
291296
doStep(1);
292297
if (completedSteps.length > 1) {
293298
} else {
294-
throw new DOMException('Simulated retryable error');
299+
throw new IndexedDbTransactionError(
300+
new Error('Simulated retryable error')
301+
);
295302
}
296303
});
297304
queue.enqueueRetryable(async () => {

packages/firestore/test/util/node_persistence.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,3 @@ if (process.env.USE_MOCK_PERSISTENCE === 'YES') {
5858

5959
globalAny.Event = Event;
6060
}
61-
62-
if (typeof DOMException === 'undefined') {
63-
// Define DOMException as it is used in tests
64-
class DOMException {
65-
constructor(readonly message: string) {}
66-
}
67-
globalAny.DOMException = DOMException;
68-
}

0 commit comments

Comments
 (0)