From 423db34bf3c405c24dfd00274e48eaa921f370b0 Mon Sep 17 00:00:00 2001 From: Alex Pitigoi Date: Tue, 24 May 2016 13:58:21 -0400 Subject: [PATCH] fix error handling when applying undefined mixins --- 3.0-RELEASE-NOTES.md | 19 ++++++++++++++++--- lib/mixins.js | 5 +++-- test/mixins.test.js | 23 ++++++++++++++++++++++- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/3.0-RELEASE-NOTES.md b/3.0-RELEASE-NOTES.md index 61e33c50..c518ed34 100644 --- a/3.0-RELEASE-NOTES.md +++ b/3.0-RELEASE-NOTES.md @@ -5,6 +5,7 @@ always describe the impact on users and instructions for upgrading applications from 2.x to 3.0. See also https://github.com/strongloop/loopback/blob/master/3.0-DEVELOPING.md +for more details. ## Always use bluebird as promise library @@ -18,7 +19,8 @@ via `global.Promise`, you will have to check all places where you are using non-standard promise API and update them to use Bluebird API instead. -Please see [Related code change](https://github.com/strongloop/loopback-datasource-juggler/pull/790) here. +See [related code change](https://github.com/strongloop/loopback-datasource-juggler/pull/790) +for more details. ## DAO.find provides ctx.data in "loaded" hook @@ -33,7 +35,8 @@ This has been fixed in 3.0 and the "loaded" hook now consistently provides checks `if (ctx.instance)` then you can remove this condition together with the branch that follows. -See also the commit [30283291](https://github.com/strongloop/loopback-datasource-juggler/commit/30283291?w=1) +See [related code change](https://github.com/strongloop/loopback-datasource-juggler/commit/30283291?w=1) +for more details. ## DAO.create no longer returns the instance(s) created @@ -47,5 +50,15 @@ We have changed the API to be consistent with other DAO methods: when invoked with a callback argument, the method does not return anything. When invoked without any callback, a promise is returned. -See [pull request 918](https://github.com/strongloop/loopback-datasource-juggler/pull/918) +See [related code change](https://github.com/strongloop/loopback-datasource-juggler/pull/918) for more details. + +## Applying an undefined mixin to a LoopBack model throws an error + +When applying an undefined mixin to a LoopBack model, a warning message was +logged regarding the invalid mixin, which needs to be addressed rather than +silently ignored. This has been fixed in 3.0, therefore an undefined mixin +applied to a LoopBack model will throw an error that needs to be handled. + +See [related code change](https://github.com/strongloop/loopback-datasource-juggler/pull/944) +for more details. \ No newline at end of file diff --git a/lib/mixins.js b/lib/mixins.js index e9e04d60..3259ccb6 100644 --- a/lib/mixins.js +++ b/lib/mixins.js @@ -44,7 +44,9 @@ MixinProvider.prototype.applyMixin = function applyMixin(modelClass, name, optio debug('Mixin is resolved to a model: %s', name); modelClass.mixin(model, options); } else { - debug('Invalid mixin: %s', name); + var errMsg = 'Model "' + modelClass.modelName + '" uses unknown mixin: ' + name; + debug(errMsg); + throw new Error(errMsg); } } }; @@ -69,4 +71,3 @@ MixinProvider.prototype.define = function defineMixin(name, mixin) { this.mixins[name] = mixin; } }; - diff --git a/test/mixins.test.js b/test/mixins.test.js index d72e8ad7..045c6e7a 100644 --- a/test/mixins.test.js +++ b/test/mixins.test.js @@ -79,11 +79,22 @@ describe('Model class', function() { properties.city.should.eql({ type: String, required: true }); }); + it('should fail to apply an undefined mixin class', function() { + var memory = new DataSource('mem', { connector: Memory }, modelBuilder); + function applyMixin() { + memory.createModel('Item', { name: 'string' }, { + mixins: { UndefinedMixin: true }, + }); + } + should.throws(applyMixin, 'failed to apply undefined mixin class'); + }); + it('should apply mixins', function(done) { var memory = new DataSource('mem', { connector: Memory }, modelBuilder); var Item = memory.createModel('Item', { name: 'string' }, { mixins: { - TimeStamp: true, Demo: { value: true }, + TimeStamp: true, + Demo: { value: true }, Multi: [ { key: 'foo', value: 'bar' }, { key: 'fox', value: 'baz' }, @@ -110,6 +121,16 @@ describe('Model class', function() { }); }); + it('should fail to apply undefined mixin', function() { + var memory = new DataSource('mem', { connector: Memory }, modelBuilder); + var Item = memory.createModel('Item', { name: 'string' }); + + function applyMixin() { + Item.mixin('UndefinedMixin', { foo: 'bar' }); + } + should.throws(applyMixin, 'failed to apply undefined mixin'); + }); + describe('#mixin()', function() { var Person, Author, Address;