Meteor 方法 + check() + audit-argument-check + async/await 导致异



我正在使用带有check((和audit-check-arguments包的meteor。

当我使用 async/await 的 meteor 方法并传递参数时,即使我使用 check(( 来验证函数参数,审计包仍然会抛出异常,指示并非所有输入参数都已检查。如果我删除异步/等待实现,包不会婴儿床。我错过了什么?

例:

Meteor.methods({
test: async function(param1){
check(param1, String);
...
await ....
}
});

引发异常:

=> Client modified -- refreshing
I20200513-10:43:27.978(5.5)? Exception while invoking method 'test' Error: Did not check() all arguments during call to 'test'
I20200513-10:43:27.979(5.5)?     at ArgumentChecker.throwUnlessAllArgumentsHaveBeenChecked (packages/check/match.js:515:13)

而这种传统的流星方法不会引发任何异常

Meteor.methods({
test:  function(param1){
check(param1, String);
...
}
});

我确定我只传递了一个参数。

看起来audit-argument-checks仅适用于同步函数。

我没有这个问题,因为我们使用mdg:validated-method,它要求您为每个方法指定一个参数验证器。

它通过用以下内容包装方法函数来关闭参数检查器:

// Silence audit-argument-checks since arguments are always checked when using this package
check(args, Match.Any);

我能想到的最简单的解决方案是将检查与异步函数分开。您可以使用包装器函数来执行此操作:

function checkAndRun(check, run) {
return function(...args) {
check.apply(this, args);
return run.apply(this, args);
}
}
Meteor.methods({
'example': checkAndRun(
function(exampleID){
check(exampleID, String);
},
async function(exampleID) {
const result = await doSomethingAsync(exampleID);
SomeDB.update({ _id: exampleID }, { $set: { someKey: result.value } });
return result.status;
}
}
});

或者您甚至可以与异步 IIFE 内联执行此操作:

Meteor.methods({
example(exampleID) {
check(exampleID, String);
return (async () => {
const result = await doSomethingAsync(exampleID);
SomeDB.update({ _id: exampleID }, { $set: { someKey: result.value } });
return result.status;
})()
}
});

想想看,这比我最初🙃能想到的最简单的解决方案要简单得多。

您只想以某种方式将同步检查与异步方法主体分开


如果您感到好奇,请潜入源代码以查看它在哪里。当该方法被调用(在ddp-server/livedata-server中(时,我们在这里结束,一个同步方法调用audit-argument-checks的第一个引用: https://github.com/meteor/meteor/blob/master/packages/ddp-server/livedata_server.js#L1767-L1770

这使我们在这里check/Match另一个同步调用:https://github.com/meteor/meteor/blob/71f67d9dbac34aba34ceef733b2b51c2bd44b665/packages/check/match.js#L114-L123

它使用奇怪的Meteor.EnvironmentVariable结构,在引擎盖下还有另一个同步调用:https://github.com/meteor/meteor/blob/master/packages/meteor/dynamics_nodejs.js#L57

最新更新