mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge pull request #12802 from meteor/making-mongo-errors-clearer
Making mongo errors clearer
This commit is contained in:
@@ -59,7 +59,7 @@ Meteor.methods({
|
||||
});
|
||||
const svg = new QRCode(uri).svg();
|
||||
|
||||
await Meteor.users.update(
|
||||
await Meteor.users.updateAsync(
|
||||
{ _id: user._id },
|
||||
{
|
||||
$set: {
|
||||
@@ -94,7 +94,7 @@ Meteor.methods({
|
||||
Accounts._handleError('Invalid 2FA code', true, 'invalid-2fa-code');
|
||||
}
|
||||
|
||||
await Meteor.users.update(
|
||||
await Meteor.users.updateAsync(
|
||||
{ _id: user._id },
|
||||
{
|
||||
$set: {
|
||||
@@ -113,7 +113,7 @@ Meteor.methods({
|
||||
throw new Meteor.Error(400, 'No user logged in.');
|
||||
}
|
||||
|
||||
await Meteor.users.update(
|
||||
await Meteor.users.updateAsync(
|
||||
{ _id: userId },
|
||||
{
|
||||
$unset: {
|
||||
|
||||
@@ -49,9 +49,9 @@ testAsyncMulti("accounts emails - reset password flow", [
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
Meteor.logout(expect((error) => {
|
||||
Meteor.logout(expect(async (error) => {
|
||||
test.equal(error, undefined);
|
||||
test.equal(Meteor.user(), null);
|
||||
test.equal(await Meteor.user(), null);
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
@@ -62,9 +62,9 @@ testAsyncMulti("accounts emails - reset password flow", [
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
Meteor.logout(expect((error) => {
|
||||
Meteor.logout(expect(async (error) => {
|
||||
test.equal(error, undefined);
|
||||
test.equal(Meteor.user(), null);
|
||||
test.equal(await Meteor.user(), null);
|
||||
}));
|
||||
}
|
||||
]);
|
||||
@@ -168,40 +168,45 @@ testAsyncMulti("accounts emails - verify email flow", [
|
||||
{email: this.email, password: 'foobar'},
|
||||
loggedIn(test, expect));
|
||||
},
|
||||
function (test, expect) {
|
||||
test.equal(Meteor.user().emails.length, 1);
|
||||
test.equal(Meteor.user().emails[0].address, this.email);
|
||||
test.isFalse(Meteor.user().emails[0].verified);
|
||||
async function (test, expect) {
|
||||
const u = await Meteor.user();
|
||||
test.equal(u.emails.length, 1);
|
||||
test.equal(u.emails[0].address, this.email);
|
||||
test.isFalse(u.emails[0].verified);
|
||||
// We should NOT be publishing things like verification tokens!
|
||||
test.isFalse(Object.prototype.hasOwnProperty.call(Meteor.user(), 'services'));
|
||||
test.isFalse(Object.prototype.hasOwnProperty.call(u, 'services'));
|
||||
},
|
||||
function (test, expect) {
|
||||
getVerifyEmailToken(this.email, test, expect);
|
||||
},
|
||||
function (test, expect) {
|
||||
// Log out, to test that verifyEmail logs us back in.
|
||||
Meteor.logout(expect((error) => {
|
||||
Meteor.logout(expect(async (error) => {
|
||||
test.equal(error, undefined);
|
||||
test.equal(Meteor.user(), null);
|
||||
test.equal(await Meteor.user(), null);
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
Accounts.verifyEmail(verifyEmailToken,
|
||||
loggedIn(test, expect));
|
||||
},
|
||||
function (test, expect) {
|
||||
test.equal(Meteor.user().emails.length, 1);
|
||||
test.equal(Meteor.user().emails[0].address, this.email);
|
||||
test.isTrue(Meteor.user().emails[0].verified);
|
||||
async function (test, expect) {
|
||||
const u = await Meteor.user();
|
||||
|
||||
test.equal(u.emails.length, 1);
|
||||
test.equal(u.emails[0].address, this.email);
|
||||
test.isTrue(u.emails[0].verified);
|
||||
},
|
||||
function (test, expect) {
|
||||
Accounts.connection.call(
|
||||
"addEmailForTestAndVerify", this.anotherEmail,
|
||||
expect((error, result) => {
|
||||
expect(async (error, result) => {
|
||||
const u = await Meteor.user();
|
||||
|
||||
test.isFalse(error);
|
||||
test.equal(Meteor.user().emails.length, 2);
|
||||
test.equal(Meteor.user().emails[1].address, this.anotherEmail);
|
||||
test.isFalse(Meteor.user().emails[1].verified);
|
||||
test.equal(u.emails.length, 2);
|
||||
test.equal(u.emails[1].address, this.anotherEmail);
|
||||
test.isFalse(u.emails[1].verified);
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
@@ -210,9 +215,9 @@ testAsyncMulti("accounts emails - verify email flow", [
|
||||
function (test, expect) {
|
||||
// Log out, to test that verifyEmail logs us back in. (And if we don't
|
||||
// do that, waitUntilLoggedIn won't be able to prevent race conditions.)
|
||||
Meteor.logout(expect((error) => {
|
||||
Meteor.logout(expect(async (error) => {
|
||||
test.equal(error, undefined);
|
||||
test.equal(Meteor.user(), null);
|
||||
test.equal(await Meteor.user(), null);
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
@@ -226,11 +231,12 @@ testAsyncMulti("accounts emails - verify email flow", [
|
||||
function (test, expect) {
|
||||
Accounts.connection.call(
|
||||
"addEmailForTestAndVerify", this.anotherEmailCaps,
|
||||
expect((error, result) => {
|
||||
expect(async (error, result) => {
|
||||
const u = await Meteor.user();
|
||||
test.isFalse(error);
|
||||
test.equal(Meteor.user().emails.length, 3);
|
||||
test.equal(Meteor.user().emails[2].address, this.anotherEmailCaps);
|
||||
test.isFalse(Meteor.user().emails[2].verified);
|
||||
test.equal(u.emails.length, 3);
|
||||
test.equal(u.emails[2].address, this.anotherEmailCaps);
|
||||
test.isFalse(u.emails[2].verified);
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
@@ -239,23 +245,25 @@ testAsyncMulti("accounts emails - verify email flow", [
|
||||
function (test, expect) {
|
||||
// Log out, to test that verifyEmail logs us back in. (And if we don't
|
||||
// do that, waitUntilLoggedIn won't be able to prevent race conditions.)
|
||||
Meteor.logout(expect((error) => {
|
||||
Meteor.logout(expect(async (error) => {
|
||||
test.equal(error, undefined);
|
||||
test.equal(Meteor.user(), null);
|
||||
test.equal(await Meteor.user(), null);
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
Accounts.verifyEmail(verifyEmailToken,
|
||||
loggedIn(test, expect));
|
||||
},
|
||||
function (test, expect) {
|
||||
test.equal(Meteor.user().emails[2].address, this.anotherEmailCaps);
|
||||
test.isTrue(Meteor.user().emails[2].verified);
|
||||
async function (test, expect) {
|
||||
const u = await Meteor.user();
|
||||
|
||||
test.equal(u.emails[2].address, this.anotherEmailCaps);
|
||||
test.isTrue(u.emails[2].verified);
|
||||
},
|
||||
function (test, expect) {
|
||||
Meteor.logout(expect((error) => {
|
||||
Meteor.logout(expect(async (error) => {
|
||||
test.equal(error, undefined);
|
||||
test.equal(Meteor.user(), null);
|
||||
test.equal(await Meteor.user(), null);
|
||||
}));
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -44,7 +44,7 @@ Meteor.methods(
|
||||
addEmailForTestAndVerify:
|
||||
async email => {
|
||||
check(email, String);
|
||||
await Meteor.users.update(
|
||||
await Meteor.users.updateAsync(
|
||||
{ _id: Accounts.userId() },
|
||||
{ $push: { emails: { address: email, verified: false } } });
|
||||
await Accounts.sendVerificationEmail(Accounts.userId(), email);
|
||||
|
||||
@@ -700,8 +700,8 @@ if (Meteor.isClient) (() => {
|
||||
// test Meteor.user(). This test properly belongs in
|
||||
// accounts-base/accounts_tests.js, but this is where the tests that
|
||||
// actually log in are.
|
||||
function (test, expect) {
|
||||
const clientUser = Meteor.user();
|
||||
async function (test, expect) {
|
||||
const clientUser = await Meteor.user();
|
||||
Accounts.connection.call('testMeteorUser', expect((err, result) => {
|
||||
test.equal(result._id, clientUser._id);
|
||||
test.equal(result.username, clientUser.username);
|
||||
|
||||
@@ -128,7 +128,7 @@ Meteor.methods(
|
||||
if (!this.userId) throw new Error("Not logged in!");
|
||||
await Meteor
|
||||
.users
|
||||
.update(this.userId, { $unset: { profile: 1, username: 1 } });
|
||||
.updateAsync(this.userId, { $unset: { profile: 1, username: 1 } });
|
||||
},
|
||||
|
||||
expireTokens:
|
||||
@@ -137,6 +137,6 @@ Meteor.methods(
|
||||
},
|
||||
|
||||
removeUser:
|
||||
async username => await Meteor.users.remove({ "username": username }),
|
||||
async username => await Meteor.users.removeAsync({ "username": username }),
|
||||
}
|
||||
);
|
||||
|
||||
@@ -18,3 +18,5 @@ export const ASYNC_COLLECTION_METHODS = [
|
||||
];
|
||||
|
||||
export const ASYNC_CURSOR_METHODS = ['count', 'fetch', 'forEach', 'map'];
|
||||
|
||||
export const CLIENT_ONLY_METHODS = ["findOne", "insert", "remove", "update", "upsert"];
|
||||
|
||||
@@ -959,7 +959,7 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
// If the user provided a callback and the collection implements this
|
||||
// operation asynchronously, then queryRet will be undefined, and the
|
||||
// result will be returned through the callback instead.
|
||||
return this._collection.updateAsync(
|
||||
return this._collection.update(
|
||||
selector,
|
||||
modifier,
|
||||
options,
|
||||
@@ -1258,18 +1258,3 @@ function popCallbackFromArgs(args) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// XXX: IN Meteor 3.x this code was not working....
|
||||
// It throws an error when trying to call a method on the collection.
|
||||
// the error normally is:
|
||||
// TypeError: this[methodName] is not a function
|
||||
// ASYNC_COLLECTION_METHODS.forEach(methodName => {
|
||||
// const methodNameAsync = getAsyncMethodName(methodName);
|
||||
// Mongo.Collection.prototype[methodNameAsync] = function(...args) {
|
||||
// try {
|
||||
// return Promise.resolve(this[methodName](...args));
|
||||
// } catch (error) {
|
||||
// return Promise.reject(error);
|
||||
// }
|
||||
// };
|
||||
// });
|
||||
|
||||
@@ -17,6 +17,7 @@ var MongoDB = NpmModuleMongodb;
|
||||
import { DocFetcher } from "./doc_fetcher.js";
|
||||
import {
|
||||
ASYNC_CURSOR_METHODS,
|
||||
CLIENT_ONLY_METHODS,
|
||||
getAsyncMethodName
|
||||
} from "meteor/minimongo/constants";
|
||||
import { Meteor } from "meteor/meteor";
|
||||
@@ -359,6 +360,7 @@ MongoConnection.prototype.insertAsync = async function (collection_name, documen
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Cause queries that may be affected by the selector to poll in this write
|
||||
// fence.
|
||||
MongoConnection.prototype._refresh = async function (collectionName, selector) {
|
||||
@@ -791,6 +793,17 @@ MongoConnection.prototype.dropIndexAsync = async function (collectionName, index
|
||||
var indexName = await collection.dropIndex(index);
|
||||
};
|
||||
|
||||
|
||||
CLIENT_ONLY_METHODS.forEach(function (m) {
|
||||
MongoConnection.prototype[m] = function () {
|
||||
throw new Error(
|
||||
`${m} + is not available on the server. Please use ${getAsyncMethodName(
|
||||
m
|
||||
)}() instead.`
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
// CURSORS
|
||||
|
||||
// There are several classes which relate to cursors:
|
||||
@@ -868,6 +881,12 @@ Cursor.prototype.countAsync = async function () {
|
||||
);
|
||||
};
|
||||
|
||||
Cursor.prototype.count = function () {
|
||||
throw new Error(
|
||||
"count() is not avaible on the server. Please use countAsync() instead."
|
||||
);
|
||||
};
|
||||
|
||||
[...ASYNC_CURSOR_METHODS, Symbol.iterator, Symbol.asyncIterator].forEach(methodName => {
|
||||
// count is handled specially since we don't want to create a cursor.
|
||||
// it is still included in ASYNC_CURSOR_METHODS because we still want an async version of it to exist.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
ASYNC_COLLECTION_METHODS,
|
||||
getAsyncMethodName
|
||||
getAsyncMethodName,
|
||||
CLIENT_ONLY_METHODS
|
||||
} from "meteor/minimongo/constants";
|
||||
|
||||
MongoInternals.RemoteCollectionDriver = function (
|
||||
@@ -30,22 +31,33 @@ Object.assign(MongoInternals.RemoteCollectionDriver.prototype, {
|
||||
open: function (name) {
|
||||
var self = this;
|
||||
var ret = {};
|
||||
REMOTE_COLLECTION_METHODS.forEach(
|
||||
function (m) {
|
||||
ret[m] = _.bind(self.mongo[m], self.mongo, name);
|
||||
REMOTE_COLLECTION_METHODS.forEach(function (m) {
|
||||
ret[m] = _.bind(self.mongo[m], self.mongo, name);
|
||||
|
||||
if (!ASYNC_COLLECTION_METHODS.includes(m)) return;
|
||||
const asyncMethodName = getAsyncMethodName(m);
|
||||
ret[asyncMethodName] = function (...args) {
|
||||
try {
|
||||
return Promise.resolve(ret[m](...args));
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
if (!ASYNC_COLLECTION_METHODS.includes(m)) return;
|
||||
const asyncMethodName = getAsyncMethodName(m);
|
||||
ret[asyncMethodName] = function (...args) {
|
||||
try {
|
||||
return Promise.resolve(ret[m](...args));
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
CLIENT_ONLY_METHODS.forEach(function (m) {
|
||||
ret[m] = _.bind(self.mongo[m], self.mongo, name);
|
||||
|
||||
ret[m] = function (...args) {
|
||||
throw new Error(
|
||||
`${m} + is not available on the server. Please use ${getAsyncMethodName(
|
||||
m
|
||||
)}() instead.`
|
||||
);
|
||||
};
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Create the singleton RemoteCollectionDriver only on demand, so we
|
||||
|
||||
Reference in New Issue
Block a user