Reputation: 1630
My meteor code goes a couple Meteor.call methods deep at some points. If I have an error in the 2nd layer and I want to throw that meteor error back to the client side how can I do that?
Currently I have something like this, but I'm getting very confusing outputs and I don't think I fully understand what is happening when I'm calling throw new Meteor.Error(500, e.category_code, e.description);
In client.js
Meteor.call('firstCall', data, function (error, result) {
if(result) {
doSomething();
}
else{
console.log(error);//just shows 500
}
});
In server.js
var Future = Meteor.npmRequire("fibers/future");
function extractFromPromise(promise) {
var fut = new Future();
promise.then(function (result) {
fut.return(result);
}, function (error) {
console.log(error);
fut.throw(error);
});
return fut.wait();
}
firstCall: function (data){
try{
Meteor.call('secondCall', data, 'http://testhref.com/test', 'http://testhref2.com/test' function (error, result) {
return result;
});
}
catch(e){
throw new Meteor.Error(500, e.category_code, e.description);
}
}
secondCall: function (data, paymentHref, otherHref){
try{
var associate = extractFromPromise(balanced.get(paymentHref).associate_to_customer(otherHref).debit({
"amount": data.paymentInformation[0].total_amount * 100,
"appears_on_statement_as": "Trash Mountain"}));
}
catch(e){
Collection.update(data.id, {
$set: {
'failed.category_code': e.category_code,
'failed.description': e.description
}
});
throw new Meteor.Error(500, e.category_code, e.description);
}
}
Upvotes: 5
Views: 3405
Reputation: 36900
In your case, the catch in firstCall
is not going to have anything defined for e.category_code
and e.description
when secondCall
throws. This is because in secondCall
you are passing these two as arguments to Meteor.Error
, which takes as its arguments error
, reason
, and details
:
https://github.com/meteor/meteor/blob/devel/packages/meteor/errors.js
In order to pass these through, you will need to amend firstCall
to use these properties:
firstCall: function (data){
try{
Meteor.call('secondCall', data, 'http://testhref.com/test', 'http://testhref2.com/test');
}
catch(e){
throw new Meteor.Error(500, e.reason, e.details);
}
}
I'm not even sure you need to split it up into two calls for modularity, as you can just use normal Javascript functions. But we can discuss that elsewhere.
Upvotes: 2
Reputation: 8698
I few things to mention here:
Meteor._wrapAsync
as I will explain later), they return the error on another way (as the first argument in NodeJS callback-style). This applies both for Meteor.call
and to your doSomeAsyncThing
.Meteor.call
on the server. Meteor.call
is meant to call server methods from the client. In this case you could just call YourObj.secondCall
from inside of firstCall
.firstCall
) doesn't have any effect. You want your async code to work as sync code, so I suggest using Meteor._wrapAsync
which is very well explained here.
So, I would implement server side a bit different:firstCall: function (data){
try{
return this.secondCall(data);
}
catch(e){
throw new Meteor.Error(500, e.category_code, e.description);
}
secondCall: function (data){
try{
return Meteor._wrapAsync(doSomeAsyncThing)(data);
}
catch(e){
Collection.update(data.id, {
$set: {
'failed.category_code': e.category_code,
'failed.description': e.description
}
});
throw new Meteor.Error(500, e.category_code, e.description);
}
Hope this helps!
Upvotes: 0