Skip to content

Commit

Permalink
Trap exceptions that are thrown from adapter methods and reject the
Browse files Browse the repository at this point in the history
store promise with the exception.

Closes #4945
  • Loading branch information
bmac committed Jan 12, 2018
1 parent 7c6448d commit cf9f70a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 6 deletions.
2 changes: 1 addition & 1 deletion addon/-private/system/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -2869,7 +2869,7 @@ function _commit(adapter, store, operation, snapshot) {
let modelClass = store._modelFor(modelName);
assert(`You tried to update a record but you have no adapter (for ${modelName})`, adapter);
assert(`You tried to update a record but your adapter (for ${modelName}) does not implement '${operation}'`, typeof adapter[operation] === 'function');
let promise = adapter[operation](store, modelClass, snapshot);
let promise = Promise.resolve().then(() => adapter[operation](store, modelClass, snapshot));
let serializer = serializerForAdapter(store, adapter, modelName);
let label = `DS: Extract and notify about ${operation} completion of ${internalModel}`;

Expand Down
10 changes: 5 additions & 5 deletions addon/-private/system/store/finders.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function payloadIsNotBlank(adapterPayload) {
export function _find(adapter, store, modelClass, id, internalModel, options) {
let snapshot = internalModel.createSnapshot(options);
let { modelName } = internalModel;
let promise = adapter.findRecord(store, modelClass, id, snapshot);
let promise = Promise.resolve().then(() => adapter.findRecord(store, modelClass, id, snapshot));
let label = `DS: Handle Adapter#findRecord of '${modelName}' with id: '${id}'`;

promise = Promise.resolve(promise, label);
Expand Down Expand Up @@ -116,7 +116,7 @@ export function _findAll(adapter, store, modelName, sinceToken, options) {
let modelClass = store.modelFor(modelName); // adapter.findAll depends on the class
let recordArray = store.peekAll(modelName);
let snapshotArray = recordArray._createSnapshot(options);
let promise = adapter.findAll(store, modelClass, sinceToken, snapshotArray);
let promise = Promise.resolve().then(() => adapter.findAll(store, modelClass, sinceToken, snapshotArray));
let label = "DS: Handle Adapter#findAll of " + modelClass;

promise = Promise.resolve(promise, label);
Expand All @@ -140,9 +140,9 @@ export function _query(adapter, store, modelName, query, recordArray) {
let promise;
if (adapter.query.length > 3) {
recordArray = recordArray || store.recordArrayManager.createAdapterPopulatedRecordArray(modelName, query);
promise = adapter.query(store, modelClass, query, recordArray);
promise = Promise.resolve().then(() => adapter.query(store, modelClass, query, recordArray));
} else {
promise = adapter.query(store, modelClass, query);
promise = Promise.resolve().then(() => adapter.query(store, modelClass, query));
}

let label = `DS: Handle Adapter#query of ${modelClass}`;
Expand Down Expand Up @@ -172,7 +172,7 @@ export function _query(adapter, store, modelName, query, recordArray) {

export function _queryRecord(adapter, store, modelName, query) {
let modelClass = store.modelFor(modelName); // adapter.queryRecord needs the class
let promise = adapter.queryRecord(store, modelClass, query);
let promise = Promise.resolve().then(() => adapter.queryRecord(store, modelClass, query));
let label = `DS: Handle Adapter#queryRecord of ${modelName}`;

promise = Promise.resolve(promise, label);
Expand Down
66 changes: 66 additions & 0 deletions tests/integration/store-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -914,4 +914,70 @@ testInDebug('store#queryRecord should assert when normalized payload of adapter
}, /Expected the primary data returned by the serializer for a 'queryRecord' response to be a single object or null but instead it was an array./);
});

test('The store should trap exceptions that are thrown from adapter#findRecord', function(assert) {
assert.expect(1)
env.adapter.findRecord = function() {
throw new Error('Refusing to find record');
};

run(() => {
store.findRecord('car', 1).catch(error => {
assert.equal(error.message, 'Refusing to find record')
})
});
});

test('The store should trap exceptions that are thrown from adapter#findAll', function(assert) {
assert.expect(1)
env.adapter.findAll = function() {
throw new Error('Refusing to find all records');
};

run(() => {
store.findAll('car').catch(error => {
assert.equal(error.message, 'Refusing to find all records')
})
});
});

test('The store should trap exceptions that are thrown from adapter#query', function(assert) {
assert.expect(1)
env.adapter.query = function() {
throw new Error('Refusing to query records');
};

run(() => {
store.query('car', {}).catch(error => {
assert.equal(error.message, 'Refusing to query records')
})
});
});

test('The store should trap exceptions that are thrown from adapter#queryRecord', function(assert) {
assert.expect(1)
env.adapter.queryRecord = function() {
throw new Error('Refusing to query record');
};

run(() => {
store.queryRecord('car', {}).catch(error => {
assert.equal(error.message, 'Refusing to query record')
})
});
});


test('The store should trap exceptions that are thrown from adapter#createRecord', function(assert) {
assert.expect(1)
env.adapter.createRecord = function() {
throw new Error('Refusing to serialize');
};

run(() => {
let car = store.createRecord('car')

car.save().catch(error => {
assert.equal(error.message, 'Refusing to serialize')
})
});
});

0 comments on commit cf9f70a

Please sign in to comment.