Test that we cant transform a user error in a NeDB error

pull/2/head
Louis Chatriot 11 years ago
parent 5b7adc9b52
commit 69f31fe3e5
  1. 9
      lib/datastore.js
  2. 40
      test/db.test.js

@ -395,20 +395,20 @@ Datastore.prototype.find = function () {
Datastore.prototype._findOne = function (query, callback) { Datastore.prototype._findOne = function (query, callback) {
var self = this var self = this
, candidates = this.getCandidates(query) , candidates = this.getCandidates(query)
, i , i, found = null
; ;
try { try {
for (i = 0; i < candidates.length; i += 1) { for (i = 0; i < candidates.length; i += 1) {
if (model.match(candidates[i], query)) { if (model.match(candidates[i], query)) {
return callback(null, model.deepCopy(candidates[i])); found = model.deepCopy(candidates[i]);
} }
} }
} catch (err) { } catch (err) {
return callback(err); return callback(err);
} }
return callback(null, null); return callback(null, found);
}; };
Datastore.prototype.findOne = function () { Datastore.prototype.findOne = function () {
@ -472,7 +472,7 @@ Datastore.prototype._update = function (query, updateQuery, options, cb) {
if (model.match(candidates[i], query) && (multi || numReplaced === 0)) { if (model.match(candidates[i], query) && (multi || numReplaced === 0)) {
numReplaced += 1; numReplaced += 1;
modifiedDoc = model.modify(candidates[i], updateQuery); modifiedDoc = model.modify(candidates[i], updateQuery);
modifications.push({ oldDoc: candidates[i], newDoc: modifiedDoc }); modifications.push({ oldDoc: candidates[i], newDoc: modifiedDoc });
} }
} }
} catch (err) { } catch (err) {
@ -542,5 +542,4 @@ Datastore.prototype.remove = function () {
}; };
module.exports = Datastore; module.exports = Datastore;

@ -220,6 +220,46 @@ describe('Database', function () {
}); });
}); });
}); });
/**
* Complicated behavior here. Basically we need to test that when a user function throws an exception, it is not caught
* in NeDB and the callback called again, transforming a user error into a NeDB error.
*
* So we need a way to check that the callback is called only once and the exception thrown is indeed the client exception
* Mocha's exception handling mechanism interferes with this since it already registers a listener on uncaughtException
* which we need to use since findOne uses I/O so the callback is not called in the same turn of the event loop (so no try/catch)
* So we remove all current listeners, put our own which when called will register the former listeners (incl. Mocha's) again.
*
* Note: maybe using an in-memory only NeDB would give us an easier solution
*/
it('If the callback throws an uncaught execption, dont catch it inside findOne, this is userspace concern', function (done) {
var tryCount = 0
, currentUncaughtExceptionHandlers = process.listeners('uncaughtException')
, i
;
process.removeAllListeners('uncaughtException');
process.on('uncaughtException', function MINE (ex) {
for (i = 0; i < currentUncaughtExceptionHandlers.length; i += 1) {
process.on('uncaughtException', currentUncaughtExceptionHandlers[i]);
}
ex.should.equal('SOME EXCEPTION');
done();
});
d.insert({ a: 5 }, function () {
d.findOne({ a : 5}, function (err, doc) {
if (tryCount === 0) {
tryCount += 1;
throw 'SOME EXCEPTION';
} else {
done('Callback was called twice');
}
});
});
});
}); // ==== End of 'Insert' ==== // }); // ==== End of 'Insert' ==== //

Loading…
Cancel
Save