Reputation: 5605
I am wondering how to properly handle errors with Meteor when using async methods. I have tried the following, but the error is being returned in the result parameter on the client callback instead of the error parameter.
Server code:
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();
}
});
Client code:
Meteor.call('myServerMethod', function (error, result) {
if(error){
console.warn(error);
}
console.log('result', result);
});
As I was saying above, 'error' is always undefined on the client side event when the HTTP.get() on the server side returned an error. I also tried replacing future.return(error);
with future.throw(error);
on the server side, but this really throws an error on the server side. The client side error parameter then gets a 500 Server Error, although the error thrown on the server was a 401 Unauthorized error.
So, is it possible to use Fiber's Future properly so that the client callback receives the same error parameter as the server callback?
Upvotes: 1
Views: 2875
Reputation: 681
According to the Meteor.Error
docs at http://docs.meteor.com/#/full/meteor_error
Methods can throw any kind of exception. But Meteor.Error is the only kind of error that a server will send to the client. If a method function throws a different exception, then it will be mapped to a sanitized version on the wire. Specifically, if the sanitizedError field on the thrown error is set to a Meteor.Error, then that error will be sent to the client. Otherwise, if no sanitized version is available, the client gets Meteor.Error(500, 'Internal server error').
Which is why you are receiving the 500 Server Error
on the client. If you want to preserve the error message and have it be sent to the client, you can do something like this:
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);
}
}
});
Upvotes: 4