Merge pull request #944 from strongloop/fix-mixin-err-handler

[SEMVER-MAJOR] throw error for undefined mixin
This commit is contained in:
Alex Pitigoi 2016-05-31 13:10:08 -04:00
commit 5b025075dc
3 changed files with 41 additions and 6 deletions

View File

@ -5,6 +5,7 @@ always describe the impact on users and instructions for upgrading
applications from 2.x to 3.0. applications from 2.x to 3.0.
See also https://github.com/strongloop/loopback/blob/master/3.0-DEVELOPING.md See also https://github.com/strongloop/loopback/blob/master/3.0-DEVELOPING.md
for more details.
## Always use bluebird as promise library ## 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 you will have to check all places where you are using non-standard promise API
and update them to use Bluebird API instead. 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 ## 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 checks `if (ctx.instance)` then you can remove this condition together with
the branch that follows. 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 ## 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 with a callback argument, the method does not return anything. When invoked
without any callback, a promise is returned. 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. 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.

View File

@ -44,7 +44,9 @@ MixinProvider.prototype.applyMixin = function applyMixin(modelClass, name, optio
debug('Mixin is resolved to a model: %s', name); debug('Mixin is resolved to a model: %s', name);
modelClass.mixin(model, options); modelClass.mixin(model, options);
} else { } 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; this.mixins[name] = mixin;
} }
}; };

View File

@ -79,11 +79,22 @@ describe('Model class', function() {
properties.city.should.eql({ type: String, required: true }); 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) { it('should apply mixins', function(done) {
var memory = new DataSource('mem', { connector: Memory }, modelBuilder); var memory = new DataSource('mem', { connector: Memory }, modelBuilder);
var Item = memory.createModel('Item', { name: 'string' }, { var Item = memory.createModel('Item', { name: 'string' }, {
mixins: { mixins: {
TimeStamp: true, Demo: { value: true }, TimeStamp: true,
Demo: { value: true },
Multi: [ Multi: [
{ key: 'foo', value: 'bar' }, { key: 'foo', value: 'bar' },
{ key: 'fox', value: 'baz' }, { 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() { describe('#mixin()', function() {
var Person, Author, Address; var Person, Author, Address;