diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 3d7f30b3..7ee53ca2 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1076,6 +1076,19 @@ describe('Cloud Code', () => { }); }); + /** + * Verifies that an afterSave hook throwing an exception + * will not prevent a successful save response from being returned + */ + it('should succeed on afterSave exception', (done) => { + Parse.Cloud.afterSave("AfterSaveTestClass", function () { + throw "Exception"; + }); + const AfterSaveTestClass = Parse.Object.extend('AfterSaveTestClass'); + const obj = new AfterSaveTestClass(); + obj.save().then(done, done.fail); + }); + describe('cloud jobs', () => { it('should define a job', (done) => { expect(() => { diff --git a/src/RestWrite.js b/src/RestWrite.js index 8dd13a32..74fa6aa8 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -13,6 +13,7 @@ var triggers = require('./triggers'); var ClientSDK = require('./ClientSDK'); import RestQuery from './RestQuery'; import _ from 'lodash'; +import logger from './logger'; // query and data are both provided in REST API format. So data // types are encoded by plain old objects. @@ -1121,7 +1122,10 @@ RestWrite.prototype.runAfterTrigger = function() { this.config.liveQueryController.onAfterSave(updatedObject.className, updatedObject, originalObject); // Run afterSave trigger - return triggers.maybeRunTrigger(triggers.Types.afterSave, this.auth, updatedObject, originalObject, this.config); + return triggers.maybeRunTrigger(triggers.Types.afterSave, this.auth, updatedObject, originalObject, this.config) + .catch(function(err) { + logger.warn('afterSave caught an error', err); + }) }; // A helper to figure out what location this operation happens at.