【问题标题】:Proper Meteor error handling with async calls using Future使用 Future 使用异步调用正确处理 Meteor 错误
【发布时间】:2015-11-08 02:28:46
【问题描述】:

我想知道在使用异步方法时如何正确处理 Meteor 的错误。我尝试了以下方法,但是客户端回调的结果参数而不是错误参数中返回了错误。

服务器代码:

Future = Npm.require('fibers/future');

Meteor.methods({
    'myServerMethod': function(){
        var future = new Future();

        // URL to some remote API
        var url = UrlOfTheApiIWantToCall;

        HTTP.get(url, {//other params as a hash},
            function (error, result) {
                if (!error) {
                    future.return(result);
                } else {
                    future.return(error);
                }
            }
        );

        return future.wait();
    }
});

客户端代码:

Meteor.call('myServerMethod', function (error, result) {
    if(error){
        console.warn(error);
    }

    console.log('result', result);
});

正如我上面所说,当服务器端的 HTTP.get() 返回错误时,客户端事件上的“错误”始终未定义。我还尝试在服务器端将future.return(error); 替换为future.throw(error);,但这确实会在服务器端引发错误。客户端错误参数然后得到 500 服务器错误,尽管在服务器上抛出的错误是 401 Unauthorized 错误。

那么,是否可以正确使用 Fiber 的 Future,让客户端回调接收到与服务器回调相同的错误参数?

【问题讨论】:

  • 不是解决方案而是澄清,HTTP 调用可以在服务器端同步var res = HTTP.get(url, {}),还有很多其他用例我们需要在服务器端使用回调,我正在寻找一个答案也很好

标签: javascript asynchronous meteor node-fibers


【解决方案1】:

根据Meteor.Error 文档http://docs.meteor.com/#/full/meteor_error

方法可以抛出任何类型的异常。但是 Meteor.Error 是服务器将发送给客户端的唯一一种错误。如果一个方法函数抛出一个不同的异常,那么它将被映射到在线上的净化版本。具体来说,如果抛出错误的 sanitizedError 字段设置为 Meteor.Error,则该错误将被发送到客户端。否则,如果没有可用的净化版本,客户端会收到 Meteor.Error(500, 'Internal server error')。

这就是您在客户端收到500 Server Error 的原因。如果您想保留错误消息并将其发送给客户端,您可以执行以下操作:

Future = Npm.require('fibers/future');

Meteor.methods({
    'myServerMethod': function(){
        var future = new Future();

        // URL to some remote API
        var url = UrlOfTheApiIWantToCall;

        HTTP.get(url, {//other params as a hash},
            function (error, result) {
                if (!error) {
                    future.return(result);
                } else {
                    future.throw(error);
                }
            }
        );

        try {
            return future.wait();
        }
        catch(err) {
            // Replace this with whatever you want sent to the client.
            throw new Meteor.Error("http-error", err);
        }
    }
});

【讨论】:

  • 我不确定我是否理解 try-catch 在 future.wait() 周围所做的事情......另外,我倾向于避免在 JS 中使用 try-catch 块,因为这会阻止整个函数被优化(见:https://github.com/petkaantonov/bluebird/wiki/Optimization-killers)。我必须抛出错误吗?我要做的就是向客户端报告错误。我觉得投掷有点苛刻。
  • 您可以将future.throw(error) 替换为throw new Meteor.Error(..., ...)
猜你喜欢
  • 2016-03-30
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 2011-10-20
  • 2011-08-14
  • 2011-04-28
  • 2018-11-12
  • 2021-11-06
相关资源
最近更新 更多