mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Change MinimongoError to accept field in a new options parameter.
This allows the field name to be dynamically introduced into the error message. Follows-up on meteor/meteor#8529.
This commit is contained in:
@@ -40,7 +40,11 @@ Minimongo = {};
|
||||
// Use it to export private functions to test in Tinytest.
|
||||
MinimongoTest = {};
|
||||
|
||||
MinimongoError = function (message) {
|
||||
MinimongoError = function (message, options={}) {
|
||||
if (typeof message === "string" && options.field) {
|
||||
message += ` for field '${options.field}'`;
|
||||
}
|
||||
|
||||
var e = new Error(message);
|
||||
e.name = "MinimongoError";
|
||||
return e;
|
||||
|
||||
@@ -163,6 +163,22 @@ Tinytest.add("minimongo - basics", function (test) {
|
||||
|
||||
});
|
||||
|
||||
Tinytest.add("minimongo - error - no options", function (test) {
|
||||
try {
|
||||
throw MinimongoError("Not fun to have errors");
|
||||
} catch (e) {
|
||||
test.equal(e.message, "Not fun to have errors");
|
||||
}
|
||||
});
|
||||
|
||||
Tinytest.add("minimongo - error - with field", function (test) {
|
||||
try {
|
||||
throw MinimongoError("Cats are no fun", { field: "mice" });
|
||||
} catch (e) {
|
||||
test.equal(e.message, "Cats are no fun for field 'mice'");
|
||||
}
|
||||
});
|
||||
|
||||
Tinytest.add("minimongo - cursors", function (test) {
|
||||
var c = new LocalCollection();
|
||||
var res;
|
||||
|
||||
@@ -185,20 +185,24 @@ var MODIFIERS = {
|
||||
$currentDate: function (target, field, arg) {
|
||||
if (typeof arg === "object" && arg.hasOwnProperty("$type")) {
|
||||
if (arg.$type !== "date") {
|
||||
throw MinimongoError("Minimongo does currently only support the date type in $currentDate modifiers: " + field);
|
||||
throw MinimongoError(
|
||||
"Minimongo does currently only support the date type " +
|
||||
"in $currentDate modifiers",
|
||||
{ field });
|
||||
}
|
||||
} else if (arg !== true) {
|
||||
throw MinimongoError("Invalid $currentDate modifier: " + field);
|
||||
throw MinimongoError("Invalid $currentDate modifier", { field });
|
||||
}
|
||||
target[field] = new Date();
|
||||
},
|
||||
$min: function (target, field, arg) {
|
||||
if (typeof arg !== "number") {
|
||||
throw MinimongoError("Modifier $min allowed for numbers only: " + field);
|
||||
throw MinimongoError("Modifier $min allowed for numbers only", { field });
|
||||
}
|
||||
if (field in target) {
|
||||
if (typeof target[field] !== "number") {
|
||||
throw MinimongoError("Cannot apply $min modifier to non-number: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $min modifier to non-number", { field });
|
||||
}
|
||||
if (target[field] > arg) {
|
||||
target[field] = arg;
|
||||
@@ -209,11 +213,12 @@ var MODIFIERS = {
|
||||
},
|
||||
$max: function (target, field, arg) {
|
||||
if (typeof arg !== "number") {
|
||||
throw MinimongoError("Modifier $max allowed for numbers only: " + field);
|
||||
throw MinimongoError("Modifier $max allowed for numbers only", { field });
|
||||
}
|
||||
if (field in target) {
|
||||
if (typeof target[field] !== "number") {
|
||||
throw MinimongoError("Cannot apply $max modifier to non-number: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $max modifier to non-number", { field });
|
||||
}
|
||||
if (target[field] < arg) {
|
||||
target[field] = arg;
|
||||
@@ -224,10 +229,11 @@ var MODIFIERS = {
|
||||
},
|
||||
$inc: function (target, field, arg) {
|
||||
if (typeof arg !== "number")
|
||||
throw MinimongoError("Modifier $inc allowed for numbers only: " + field);
|
||||
throw MinimongoError("Modifier $inc allowed for numbers only", { field });
|
||||
if (field in target) {
|
||||
if (typeof target[field] !== "number")
|
||||
throw MinimongoError("Cannot apply $inc modifier to non-number: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $inc modifier to non-number", { field });
|
||||
target[field] += arg;
|
||||
} else {
|
||||
target[field] = arg;
|
||||
@@ -235,12 +241,13 @@ var MODIFIERS = {
|
||||
},
|
||||
$set: function (target, field, arg) {
|
||||
if (!_.isObject(target)) { // not an array or an object
|
||||
var e = MinimongoError("Cannot set property on non-object field: " + field);
|
||||
var e = MinimongoError(
|
||||
"Cannot set property on non-object field", { field });
|
||||
e.setPropertyError = true;
|
||||
throw e;
|
||||
}
|
||||
if (target === null) {
|
||||
var e = MinimongoError("Cannot set property on null: " + field);
|
||||
var e = MinimongoError("Cannot set property on null", { field });
|
||||
e.setPropertyError = true;
|
||||
throw e;
|
||||
}
|
||||
@@ -267,7 +274,8 @@ var MODIFIERS = {
|
||||
if (target[field] === undefined)
|
||||
target[field] = [];
|
||||
if (!(target[field] instanceof Array))
|
||||
throw MinimongoError("Cannot apply $push modifier to non-array: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $push modifier to non-array", { field });
|
||||
|
||||
if (!(arg && arg.$each)) {
|
||||
// Simple mode: not $each
|
||||
@@ -278,16 +286,17 @@ var MODIFIERS = {
|
||||
// Fancy mode: $each (and maybe $slice and $sort and $position)
|
||||
var toPush = arg.$each;
|
||||
if (!(toPush instanceof Array))
|
||||
throw MinimongoError("$each must be an array: " + field);
|
||||
throw MinimongoError("$each must be an array", { field });
|
||||
|
||||
// Parse $position
|
||||
var position = undefined;
|
||||
if ('$position' in arg) {
|
||||
if (typeof arg.$position !== "number")
|
||||
throw MinimongoError("$position must be a numeric value: " + field);
|
||||
throw MinimongoError("$position must be a numeric value", { field });
|
||||
// XXX should check to make sure integer
|
||||
if (arg.$position < 0)
|
||||
throw MinimongoError("$position in $push must be zero or positive: " + field);
|
||||
throw MinimongoError(
|
||||
"$position in $push must be zero or positive", { field });
|
||||
position = arg.$position;
|
||||
}
|
||||
|
||||
@@ -295,10 +304,11 @@ var MODIFIERS = {
|
||||
var slice = undefined;
|
||||
if ('$slice' in arg) {
|
||||
if (typeof arg.$slice !== "number")
|
||||
throw MinimongoError("$slice must be a numeric value: " + field);
|
||||
throw MinimongoError("$slice must be a numeric value", { field });
|
||||
// XXX should check to make sure integer
|
||||
if (arg.$slice > 0)
|
||||
throw MinimongoError("$slice in $push must be zero or negative: " + field);
|
||||
throw MinimongoError(
|
||||
"$slice in $push must be zero or negative", { field });
|
||||
slice = arg.$slice;
|
||||
}
|
||||
|
||||
@@ -306,7 +316,7 @@ var MODIFIERS = {
|
||||
var sortFunction = undefined;
|
||||
if (arg.$sort) {
|
||||
if (slice === undefined)
|
||||
throw MinimongoError("$sort requires $slice to be present: " + field);
|
||||
throw MinimongoError("$sort requires $slice to be present", { field });
|
||||
// XXX this allows us to use a $sort whose value is an array, but that's
|
||||
// actually an extension of the Node driver, so it won't work
|
||||
// server-side. Could be confusing!
|
||||
@@ -315,7 +325,7 @@ var MODIFIERS = {
|
||||
for (var i = 0; i < toPush.length; i++) {
|
||||
if (LocalCollection._f._type(toPush[i]) !== 3) {
|
||||
throw MinimongoError("$push like modifiers using $sort " +
|
||||
"require all elements to be objects: " + field);
|
||||
"require all elements to be objects", { field });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,7 +360,8 @@ var MODIFIERS = {
|
||||
if (x === undefined)
|
||||
target[field] = arg;
|
||||
else if (!(x instanceof Array))
|
||||
throw MinimongoError("Cannot apply $pushAll modifier to non-array: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $pushAll modifier to non-array", { field });
|
||||
else {
|
||||
for (var i = 0; i < arg.length; i++)
|
||||
x.push(arg[i]);
|
||||
@@ -371,7 +382,8 @@ var MODIFIERS = {
|
||||
if (x === undefined)
|
||||
target[field] = values;
|
||||
else if (!(x instanceof Array))
|
||||
throw MinimongoError("Cannot apply $addToSet modifier to non-array: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $addToSet modifier to non-array", { field });
|
||||
else {
|
||||
_.each(values, function (value) {
|
||||
for (var i = 0; i < x.length; i++)
|
||||
@@ -388,7 +400,8 @@ var MODIFIERS = {
|
||||
if (x === undefined)
|
||||
return;
|
||||
else if (!(x instanceof Array))
|
||||
throw MinimongoError("Cannot apply $pop modifier to non-array: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $pop modifier to non-array", { field });
|
||||
else {
|
||||
if (typeof arg === 'number' && arg < 0)
|
||||
x.splice(0, 1);
|
||||
@@ -403,7 +416,8 @@ var MODIFIERS = {
|
||||
if (x === undefined)
|
||||
return;
|
||||
else if (!(x instanceof Array))
|
||||
throw MinimongoError("Cannot apply $pull/pullAll modifier to non-array: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $pull/pullAll modifier to non-array", { field });
|
||||
else {
|
||||
var out = [];
|
||||
if (arg != null && typeof arg === "object" && !(arg instanceof Array)) {
|
||||
@@ -430,14 +444,16 @@ var MODIFIERS = {
|
||||
},
|
||||
$pullAll: function (target, field, arg) {
|
||||
if (!(typeof arg === "object" && arg instanceof Array))
|
||||
throw MinimongoError("Modifier $pushAll/pullAll allowed for arrays only: " + field);
|
||||
throw MinimongoError(
|
||||
"Modifier $pushAll/pullAll allowed for arrays only", { field });
|
||||
if (target === undefined)
|
||||
return;
|
||||
var x = target[field];
|
||||
if (x === undefined)
|
||||
return;
|
||||
else if (!(x instanceof Array))
|
||||
throw MinimongoError("Cannot apply $pull/pullAll modifier to non-array: " + field);
|
||||
throw MinimongoError(
|
||||
"Cannot apply $pull/pullAll modifier to non-array", { field });
|
||||
else {
|
||||
var out = [];
|
||||
for (var i = 0; i < x.length; i++) {
|
||||
@@ -457,15 +473,17 @@ var MODIFIERS = {
|
||||
$rename: function (target, field, arg, keypath, doc) {
|
||||
if (keypath === arg)
|
||||
// no idea why mongo has this restriction..
|
||||
throw MinimongoError("$rename source must differ from target: " + field);
|
||||
throw MinimongoError("$rename source must differ from target", { field });
|
||||
if (target === null)
|
||||
throw MinimongoError("$rename source field invalid: " + field);
|
||||
throw MinimongoError("$rename source field invalid", { field });
|
||||
if (typeof arg !== "string")
|
||||
throw MinimongoError("$rename target must be a string: " + field);
|
||||
throw MinimongoError("$rename target must be a string", { field });
|
||||
if (arg.indexOf('\0') > -1) {
|
||||
// Null bytes are not allowed in Mongo field names
|
||||
// https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names
|
||||
throw MinimongoError("The 'to' field for $rename cannot contain an embedded null byte: " + field);
|
||||
throw MinimongoError(
|
||||
"The 'to' field for $rename cannot contain an embedded null byte",
|
||||
{ field });
|
||||
}
|
||||
if (target === undefined)
|
||||
return;
|
||||
@@ -475,13 +493,13 @@ var MODIFIERS = {
|
||||
var keyparts = arg.split('.');
|
||||
var target2 = findModTarget(doc, keyparts, {forbidArray: true});
|
||||
if (target2 === null)
|
||||
throw MinimongoError("$rename target field invalid: " + field);
|
||||
throw MinimongoError("$rename target field invalid", { field });
|
||||
var field2 = keyparts.pop();
|
||||
target2[field2] = v;
|
||||
},
|
||||
$bit: function (target, field, arg) {
|
||||
// XXX mongo only supports $bit on integers, and we only support
|
||||
// native javascript numbers (doubles) so far, so we can't support $bit
|
||||
throw MinimongoError("$bit is not supported: " + field);
|
||||
throw MinimongoError("$bit is not supported", { field });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ Package.onUse(function (api) {
|
||||
api.export('LocalCollection');
|
||||
api.export('Minimongo');
|
||||
api.export('MinimongoTest', { testOnly: true });
|
||||
api.export('MinimongoError', { testOnly: true });
|
||||
api.use([
|
||||
'underscore',
|
||||
'ejson',
|
||||
|
||||
Reference in New Issue
Block a user