Skip to content

Commit d1b2b01

Browse files
committed
readSnapshots rejection - More code review updates
1 parent 3fe83f3 commit d1b2b01

File tree

4 files changed

+46
-29
lines changed

4 files changed

+46
-29
lines changed

lib/agent.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -465,21 +465,18 @@ function getResultsData(results) {
465465

466466
function getMapResult(snapshotMap) {
467467
var data = {};
468-
var errorMap = {};
469-
var hasSnapshotError = false;
470468
for (var id in snapshotMap) {
471469
var mapValue = snapshotMap[id];
472470
// fetchBulk / subscribeBulk map data can have either a Snapshot or an object
473471
// `{error: Error | string}` as a value.
474472
if (mapValue.error) {
475-
hasSnapshotError = true;
476473
// Transform errors to serialization-friendly objects.
477-
errorMap[id] = getReplyErrorObject(mapValue.error);
474+
data[id] = {error: getReplyErrorObject(mapValue.error)};
478475
} else {
479476
data[id] = getSnapshotData(mapValue);
480477
}
481478
}
482-
return hasSnapshotError ? {data: data, errorMap: errorMap} : {data: data};
479+
return {data: data};
483480
}
484481

485482
function getSnapshotData(snapshot) {

lib/client/connection.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,18 @@ function wrapErrorData(errorData, fullMessage) {
275275
Connection.prototype._handleBulkMessage = function(err, message, method) {
276276
if (message.data) {
277277
for (var id in message.data) {
278+
var dataForId = message.data[id];
278279
var doc = this.getExisting(message.c, id);
279-
if (doc) doc[method](err, message.data[id]);
280-
}
281-
// Handle doc-specific errors.
282-
for (var id in message.errorMap) {
283-
var doc = this.getExisting(message.c, id);
284-
if (doc) doc[method](wrapErrorData(message.errorMap[id]));
280+
if (doc) {
281+
if (err) {
282+
doc[method](err);
283+
} else if (dataForId.error) {
284+
// Bulk reply snapshot-specific errorr - see agent.js getMapResult
285+
doc[method](wrapErrorData(dataForId.error));
286+
} else {
287+
doc[method](null, dataForId);
288+
}
289+
}
285290
}
286291
} else if (Array.isArray(message.b)) {
287292
for (var i = 0; i < message.b.length; i++) {

lib/read-snapshots-request.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ function ReadSnapshotsRequest(collection, snapshots, snapshotType) {
3232
*
3333
* If the error has a `code` property of `"ERR_SNAPSHOT_READ_SILENT_REJECTION"`, then the Share
3434
* client will not pass the error to user code, but will still do things like cancel subscriptions.
35+
* The `#rejectSnapshotReadSilent(snapshot, errorMessage)` method can also be used for convenience.
3536
*
3637
* @param {Snapshot} snapshot
3738
* @param {string | Error} error
3839
*
40+
* @see #rejectSnapshotReadSilent
3941
* @see ShareDBError.CODES.ERR_SNAPSHOT_READ_SILENT_REJECTION
4042
* @see ShareDBError.CODES.ERR_SNAPSHOT_READS_REJECTED
4143
*/
@@ -46,6 +48,24 @@ ReadSnapshotsRequest.prototype.rejectSnapshotRead = function(snapshot, error) {
4648
this._idToError[snapshot.id] = error;
4749
};
4850

51+
/**
52+
* Rejects the read of a specific snapshot. A rejected snapshot read will not have that snapshot's
53+
* data sent down to the client.
54+
*
55+
* This method will set a special error code that causes the Share client to not pass the error to
56+
* user code, though it will still do things like cancel subscriptions.
57+
*
58+
* @param {Snapshot} snapshot
59+
* @param {string} errorMessage
60+
*/
61+
ReadSnapshotsRequest.prototype.rejectSnapshotReadSilent = function(snapshot, errorMessage) {
62+
this.rejectSnapshotRead(snapshot, this.silentRejectionError(errorMessage));
63+
};
64+
65+
ReadSnapshotsRequest.prototype.silentRejectionError = function(errorMessage) {
66+
return new ShareDBError(ShareDBError.CODES.ERR_SNAPSHOT_READ_SILENT_REJECTION, errorMessage);
67+
};
68+
4969
/**
5070
* Returns whether this trigger of "readSnapshots" has had a snapshot read rejected.
5171
*/

test/client/subscribe.js

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
var expect = require('chai').expect;
22
var async = require('async');
3-
var ERROR_CODES = require('../../lib/error').CODES;
43

54
module.exports = function() {
65
describe('client subscribe', function() {
@@ -47,7 +46,7 @@ module.exports = function() {
4746
});
4847

4948
function testSingleSnapshotSpecificError(label, fns) {
50-
var createReadSnapshotsError = fns.createReadSnapshotsError;
49+
var rejectSnapshot = fns.rejectSnapshot;
5150
var verifyClientError = fns.verifyClientError;
5251
it(method + ' single with readSnapshots rejectSnapshotRead ' + label, function(done) {
5352
var backend = this.backend;
@@ -59,7 +58,7 @@ module.exports = function() {
5958
backend.use('readSnapshots', function(context, cb) {
6059
expect(context.snapshots).to.be.an('array').of.length(1);
6160
expect(context.snapshots[0]).to.have.property('id', 'fido');
62-
context.rejectSnapshotRead(context.snapshots[0], createReadSnapshotsError());
61+
rejectSnapshot(context, context.snapshots[0]);
6362
cb();
6463
});
6564

@@ -94,18 +93,16 @@ module.exports = function() {
9493
});
9594
}
9695
testSingleSnapshotSpecificError('normal error', {
97-
createReadSnapshotsError: function() {
98-
return new Error('Failed to fetch fido');
96+
rejectSnapshot: function(context, snapshot) {
97+
context.rejectSnapshotRead(snapshot, new Error('Failed to fetch fido'));
9998
},
10099
verifyClientError: function(err) {
101100
expect(err).to.be.an('error').with.property('message', 'Failed to fetch fido');
102101
}
103102
});
104-
testSingleSnapshotSpecificError('special ignorable error', {
105-
createReadSnapshotsError: function() {
106-
var err = new Error('Failed to fetch fido');
107-
err.code = ERROR_CODES.ERR_SNAPSHOT_READ_SILENT_REJECTION;
108-
return err;
103+
testSingleSnapshotSpecificError('silent error', {
104+
rejectSnapshot: function(context, snapshot) {
105+
context.rejectSnapshotReadSilent(snapshot, 'Failed to fetch fido');
109106
},
110107
verifyClientError: function(err) {
111108
expect(err).to.equal(undefined);
@@ -222,7 +219,7 @@ module.exports = function() {
222219
});
223220

224221
function testBulkSnapshotSpecificError(label, fns) {
225-
var createReadSnapshotsError = fns.createReadSnapshotsError;
222+
var rejectSnapshot = fns.rejectSnapshot;
226223
var verifyClientError = fns.verifyClientError;
227224
it(method + ' bulk with readSnapshots rejectSnapshotRead ' + label, function(done) {
228225
var backend = this.backend;
@@ -241,7 +238,7 @@ module.exports = function() {
241238
backend.use('readSnapshots', function(context, cb) {
242239
expect(context.snapshots).to.be.an('array').of.length(2);
243240
expect(context.snapshots[0]).to.have.property('id', 'fido');
244-
context.rejectSnapshotRead(context.snapshots[0], createReadSnapshotsError());
241+
rejectSnapshot(context, context.snapshots[0]);
245242
cb();
246243
});
247244

@@ -294,18 +291,16 @@ module.exports = function() {
294291
});
295292
}
296293
testBulkSnapshotSpecificError('normal error', {
297-
createReadSnapshotsError: function() {
298-
return new Error('Failed to fetch fido');
294+
rejectSnapshot: function(context, snapshot) {
295+
context.rejectSnapshotRead(snapshot, new Error('Failed to fetch fido'));
299296
},
300297
verifyClientError: function(err) {
301298
expect(err).to.be.an('error').with.property('message', 'Failed to fetch fido');
302299
}
303300
});
304301
testBulkSnapshotSpecificError('special ignorable error', {
305-
createReadSnapshotsError: function() {
306-
var err = new Error('Failed to fetch fido');
307-
err.code = ERROR_CODES.ERR_SNAPSHOT_READ_SILENT_REJECTION;
308-
return err;
302+
rejectSnapshot: function(context, snapshot) {
303+
context.rejectSnapshotReadSilent(snapshot, 'Failed to fetch fido');
309304
},
310305
verifyClientError: function(err) {
311306
expect(err).to.equal(undefined);

0 commit comments

Comments
 (0)