Skip to content

Commit 51f6a8b

Browse files
authored
Mapper: clarify error message when mapping info not found
1 parent 428f728 commit 51f6a8b

File tree

4 files changed

+72
-28
lines changed

4 files changed

+72
-28
lines changed

lib/mapping/mapper.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,17 @@ class Mapper {
9292

9393
if (mappingInfo === undefined) {
9494
if (!this.client.keyspace) {
95-
throw new Error(
96-
'You must set the Client keyspace or specify the keyspace of the model in the MappingOptions');
95+
throw new Error(`No mapping information found for model '${name}'. ` +
96+
`Mapper is unable to create default mappings without setting the keyspace`);
9797
}
9898

9999
mappingInfo = ModelMappingInfo.createDefault(name, this.client.keyspace);
100+
this.client.log('info', `Mapping information for model '${name}' not found, creating default mapping. ` +
101+
`Keyspace: ${mappingInfo.keyspace}; Table: ${mappingInfo.tables[0].name}.`);
102+
} else {
103+
this.client.log('info', `Creating model mapper for '${name}' using mapping information. Keyspace: ${
104+
mappingInfo.keyspace}; Table${mappingInfo.tables.length > 1? 's' : ''}: ${
105+
mappingInfo.tables.map(t => t.name)}.`);
100106
}
101107

102108
modelMapper = new ModelMapper(name, new MappingHandler(this.client, mappingInfo));

test/unit/mapping/mapper-tests.js

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
'use strict';
1818

19-
const assert = require('assert');
19+
const { assert } = require('chai');
20+
const sinon = require('sinon');
2021
const Mapper = require('../../../lib/mapping/mapper');
22+
const ModelMapper = require('../../../lib/mapping/model-mapper');
2123
const helper = require('../../test-helper');
2224
const mapperTestHelper = require('./mapper-unit-test-helper');
2325

@@ -60,7 +62,40 @@ describe('Mapper', () => {
6062
it('should validate that the client keyspace is set when mapping options has not been specified', () => {
6163
const mapper = new Mapper({});
6264
assert.throws(() => mapper.forModel('Sample'),
63-
/You must set the Client keyspace or specify the keyspace of the model in the MappingOptions/);
65+
/No mapping information found for model 'Sample'\. Mapper .+ without setting the keyspace$/);
66+
});
67+
68+
it('should log when creating a ModelMapper instance using mapping information', () => {
69+
const client = sinon.spy({ log: () => {} });
70+
const mapper = new Mapper(client, { models: { 'T': { tables: ['t1', 't2'], keyspace: 'ks1' }}});
71+
72+
// call forModel() multiple times
73+
for (let i = 0; i < 10; i++) {
74+
const m = mapper.forModel('T');
75+
assert.instanceOf(m, ModelMapper);
76+
}
77+
78+
// Only should be logged once
79+
assert.ok(client.log.calledOnce);
80+
const args = client.log.getCall(0).args;
81+
assert.strictEqual(args[0], 'info');
82+
assert.match(args[1], /Creating model mapper for 'T' using mapping information. Keyspace: ks1; Tables: t1,t2.$/);
83+
});
84+
85+
it('should log when creating a ModelMapper instance using defaults', () => {
86+
const client = sinon.spy({ log: () => {}, keyspace: 'abc' });
87+
const mapper = new Mapper(client);
88+
89+
// call forModel() multiple times
90+
for (let i = 0; i < 10; i++) {
91+
const m = mapper.forModel('user');
92+
assert.instanceOf(m, ModelMapper);
93+
}
94+
95+
assert.ok(client.log.calledOnce);
96+
const args = client.log.getCall(0).args;
97+
assert.strictEqual(args[0], 'info');
98+
assert.match(args[1], /Mapping information for model 'user' not found, creating .+Keyspace: abc; Table: user.$/);
6499
});
65100
});
66101

test/unit/mapping/model-mapper-mutation-tests.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ describe('ModelMapper', () => {
6666
const client = {
6767
connect: () => Promise.resolve(),
6868
keyspace: 'ks1',
69+
log: () => {},
6970
metadata: {
7071
getTable: () => Promise.reject(error)
7172
}
@@ -99,7 +100,7 @@ describe('ModelMapper', () => {
99100
}
100101
]));
101102

102-
it('should warn when cache reaches 100 different queries', () => {
103+
it('should warn when cache reaches 100 different queries', async () => {
103104
const clientInfo = mapperTestHelper.getClient(['id1'], [ 1 ], 'ks1');
104105
const modelMapper = mapperTestHelper.getModelMapper(clientInfo);
105106

@@ -110,16 +111,17 @@ describe('ModelMapper', () => {
110111
promises.push(modelMapper.insert({ id1: 1, [`col${i % (cacheHighWaterMark-1)}`]: 1}));
111112
}
112113

113-
return Promise.all(promises)
114-
// No warnings logged when there are 99 different queries
115-
.then(() => assert.strictEqual(clientInfo.logMessages.length, 0))
116-
// One more query
117-
.then(() => modelMapper.insert({ id1: 1, anotherColumn: 1 }))
118-
.then(() => {
119-
assert.strictEqual(clientInfo.logMessages.length, 1);
120-
assert.strictEqual(clientInfo.logMessages[0].level, 'warning');
121-
helper.assertContains(clientInfo.logMessages[0].message, `ModelMapper cache reached ${cacheHighWaterMark}`);
122-
});
114+
await Promise.all(promises);
115+
116+
// No warnings logged when there are 99 different queries
117+
assert.strictEqual(clientInfo.logMessages.filter(l => l.level === 'warning').length, 0);
118+
119+
// One more query
120+
await modelMapper.insert({ id1: 1, anotherColumn: 1 });
121+
122+
const warnings = clientInfo.logMessages.filter(l => l.level === 'warning');
123+
assert.strictEqual(warnings.length, 1);
124+
helper.assertContains(warnings[0].message, `ModelMapper cache reached ${cacheHighWaterMark}`);
123125
});
124126

125127
it('should use the mapping function in the insert values', () => testQueries({

test/unit/mapping/model-mapper-select-tests.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ describe('ModelMapper', () => {
285285
});
286286

287287
describe('#mapWithQuery', () => {
288-
it('should warn when cache reaches 100 different queries', () => {
288+
it('should warn when cache reaches 100 different queries', async () => {
289289
const clientInfo = mapperTestHelper.getClient(['id1'], [ 1 ], 'ks1', emptyResponse);
290290
const modelMapper = mapperTestHelper.getModelMapper(clientInfo);
291291

@@ -297,18 +297,19 @@ describe('ModelMapper', () => {
297297
promises.push(executor());
298298
}
299299

300-
return Promise.all(promises)
301-
// No warnings logged when there are 99 different queries
302-
.then(() => assert.strictEqual(clientInfo.logMessages.length, 0))
303-
// One more query
304-
.then(() => modelMapper.mapWithQuery(`query-limit`, () => [])())
305-
.then(() => {
306-
assert.strictEqual(clientInfo.logMessages.length, 1);
307-
assert.strictEqual(clientInfo.logMessages[0].level, 'warning');
308-
assert.strictEqual(clientInfo.logMessages[0].message,
309-
`Custom queries cache reached ${cacheHighWaterMark} items, this could be caused by ` +
310-
`hard-coding parameter values inside the query, which should be avoided`);
311-
});
300+
await Promise.all(promises);
301+
302+
// No warnings logged when there are 99 different queries
303+
assert.strictEqual(clientInfo.logMessages.filter(l => l.level === 'warning').length, 0);
304+
305+
// One more query
306+
await modelMapper.mapWithQuery(`query-limit`, () => [])();
307+
308+
const warnings = clientInfo.logMessages.filter(l => l.level === 'warning');
309+
assert.strictEqual(warnings.length, 1);
310+
assert.strictEqual(warnings[0].message,
311+
`Custom queries cache reached ${cacheHighWaterMark} items, this could be caused by ` +
312+
`hard-coding parameter values inside the query, which should be avoided`);
312313
});
313314
});
314315
});

0 commit comments

Comments
 (0)