Skip to content

Commit d51c676

Browse files
Review
1 parent f28e510 commit d51c676

File tree

5 files changed

+47
-42
lines changed

5 files changed

+47
-42
lines changed

packages/firestore/src/core/event_manager.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import { Query } from './query';
2222
import { SyncEngine, SyncEngineListener } from './sync_engine';
2323
import { OnlineState } from './types';
2424
import { ChangeType, DocumentViewChange, ViewSnapshot } from './view_snapshot';
25+
import { logError } from '../util/log';
26+
import { Code, FirestoreError } from '../util/error';
27+
28+
const LOG_TAG = 'EventManager';
2529

2630
/**
2731
* Holds the listeners and the last received ViewSnapshot for a query being
@@ -69,10 +73,21 @@ export class EventManager implements SyncEngineListener {
6973
}
7074

7175
if (firstListen) {
72-
queryInfo.viewSnap = await this.syncEngine.listen(query);
76+
try {
77+
queryInfo.viewSnap = await this.syncEngine.listen(query);
78+
} catch (e) {
79+
const msg = `Initialization of query '${query}' failed: ${e}`;
80+
logError(LOG_TAG, msg);
81+
if (e.name === 'IndexedDbTransactionError') {
82+
listener.onError(new FirestoreError(Code.UNAVAILABLE, msg));
83+
} else {
84+
throw e;
85+
}
86+
return;
87+
}
7388
}
7489

75-
this.queries.set(query, queryInfo!);
90+
this.queries.set(query, queryInfo);
7691
queryInfo.listeners.push(listener);
7792

7893
// Run global snapshot listeners if a consistent snapshot has been emitted.

packages/firestore/src/core/firestore_client.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { Datastore } from '../remote/datastore';
2727
import { RemoteStore } from '../remote/remote_store';
2828
import { AsyncQueue } from '../util/async_queue';
2929
import { Code, FirestoreError } from '../util/error';
30-
import { logDebug, logError } from '../util/log';
30+
import { logDebug } from '../util/log';
3131
import { Deferred } from '../util/promise';
3232
import {
3333
EventManager,
@@ -398,23 +398,7 @@ export class FirestoreClient {
398398
): QueryListener {
399399
this.verifyNotTerminated();
400400
const listener = new QueryListener(query, observer, options);
401-
this.asyncQueue.enqueueAndForget(async () => {
402-
try {
403-
await this.eventMgr.listen(listener);
404-
} catch (e) {
405-
logError(LOG_TAG, `Failed to register query: ${e}`);
406-
if (e.name === 'IndexedDbTransactionError') {
407-
listener.onError(
408-
new FirestoreError(
409-
Code.UNAVAILABLE,
410-
`Failed to register query: ${e}`
411-
)
412-
);
413-
} else {
414-
throw e;
415-
}
416-
}
417-
});
401+
this.asyncQueue.enqueueAndForget(() => this.eventMgr.listen(listener));
418402
return listener;
419403
}
420404

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => {
174174
.expectEvents(query1, {})
175175
.failDatabase()
176176
.userListens(query2)
177-
.expectEvents(query2, { errorCode: Code.UNKNOWN })
177+
.expectEvents(query2, { errorCode: Code.UNAVAILABLE })
178178
.recoverDatabase()
179179
.userListens(query3)
180180
.watchAcksFull(query3, 1)
@@ -190,7 +190,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => {
190190
.expectEvents(query1, {})
191191
.failDatabase()
192192
.userListens(query2)
193-
.expectEvents(query2, { errorCode: Code.UNKNOWN })
193+
.expectEvents(query2, { errorCode: Code.UNAVAILABLE })
194194
.recoverDatabase()
195195
.userListens(query2)
196196
.watchAcksFull(query2, 1)

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

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import {
7070
} from '../../../src/remote/watch_change';
7171
import { debugAssert, fail } from '../../../src/util/assert';
7272
import { AsyncQueue, TimerId } from '../../../src/util/async_queue';
73-
import { Code, FirestoreError } from '../../../src/util/error';
73+
import { FirestoreError } from '../../../src/util/error';
7474
import { primitiveComparator } from '../../../src/util/misc';
7575
import { forEach, objectSize } from '../../../src/util/obj';
7676
import { ObjectMap } from '../../../src/util/obj_map';
@@ -80,7 +80,7 @@ import {
8080
deletedDoc,
8181
deleteMutation,
8282
doc,
83-
expectFirestoreError,
83+
validateFirestoreError,
8484
filter,
8585
key,
8686
orderBy,
@@ -358,7 +358,7 @@ class EventAggregator implements Observer<ViewSnapshot> {
358358
}
359359

360360
error(error: Error): void {
361-
expectFirestoreError(error);
361+
expect(error.name).to.equal('FirebaseError');
362362
this.pushEvent({ query: this.query, error: error as FirestoreError });
363363
}
364364
}
@@ -597,9 +597,16 @@ abstract class TestRunner {
597597
}
598598

599599
private async doListen(listenSpec: SpecUserListen): Promise<void> {
600+
let targetFailed = false;
601+
600602
const querySpec = listenSpec[1];
601603
const query = parseQuery(querySpec);
602-
const aggregator = new EventAggregator(query, this.pushEvent.bind(this));
604+
const aggregator = new EventAggregator(query, e => {
605+
if (e.error) {
606+
targetFailed = true;
607+
}
608+
this.pushEvent(e);
609+
});
603610
// TODO(dimond): Allow customizing listen options in spec tests
604611
const options = {
605612
includeMetadataChanges: true,
@@ -608,20 +615,11 @@ abstract class TestRunner {
608615
const queryListener = new QueryListener(query, aggregator, options);
609616
this.queryListeners.set(query, queryListener);
610617

611-
const targetAdded = await this.queue.enqueue(async () => {
612-
try {
613-
await this.eventManager.listen(queryListener);
614-
return true;
615-
} catch (e) {
616-
expect(this.persistence.injectFailures).to.be.true;
617-
queryListener.onError(
618-
new FirestoreError(Code.UNAVAILABLE, e.message)
619-
);
620-
return false;
621-
}
622-
});
618+
await this.queue.enqueue(() => this.eventManager.listen(queryListener));
623619

624-
if (targetAdded) {
620+
if (targetFailed) {
621+
expect(this.persistence.injectFailures).to.be.true;
622+
} else {
625623
// Skip the backoff that may have been triggered by a previous call to
626624
// `watchStreamCloses()`.
627625
if (
@@ -1206,7 +1204,10 @@ abstract class TestRunner {
12061204
const expectedQuery = parseQuery(expected.query);
12071205
expect(actual.query).to.deep.equal(expectedQuery);
12081206
if (expected.errorCode) {
1209-
expectFirestoreError(actual.error!);
1207+
validateFirestoreError(
1208+
mapCodeFromRpcCode(expected.errorCode),
1209+
actual.error!
1210+
);
12101211
} else {
12111212
const expectedChanges: DocumentViewChange[] = [];
12121213
if (expected.removed) {

packages/firestore/test/util/helpers.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ import { ByteString } from '../../src/util/byte_string';
9292
import { PlatformSupport } from '../../src/platform/platform';
9393
import { JsonProtoSerializer } from '../../src/remote/serializer';
9494
import { Timestamp } from '../../src/api/timestamp';
95+
import { Code, FirestoreError } from '../../src/util/error';
9596

9697
/* eslint-disable no-restricted-globals */
9798

@@ -819,8 +820,12 @@ export function expectEqualitySets<T>(
819820
}
820821
}
821822

822-
export function expectFirestoreError(err: Error): void {
823-
expect(err.name).to.equal('FirebaseError');
823+
export function validateFirestoreError(
824+
expectedCode: Code,
825+
actualError: Error
826+
): void {
827+
expect(actualError.name).to.equal('FirebaseError');
828+
expect((actualError as FirestoreError).code).to.equal(expectedCode);
824829
}
825830

826831
export function forEachNumber<V>(

0 commit comments

Comments
 (0)