2014-09-12 4 views
5

Mein Meteor Code geht ein paar Meteor.call Methoden tief an einigen Punkten. Wenn ich einen Fehler in der 2. Schicht habe und diesen Meteorfehler zurück zur Kundenseite werfen möchte, wie kann ich das tun?Wie gebe ich einen Fehler von einer Meteor.call-Methode in einem anderen Meteor.call zurück

Zur Zeit habe ich so etwas, aber ich bin immer sehr verwirrend Ausgänge und ich glaube nicht vollständig verstehe ich, was passiert, wenn ich rufe 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); 
    } 
} 

Antwort

2

In Ihrem Fall wird der Catch in firstCall nichts für e.category_code und e.description definiert haben, wenn secondCall wirft. Dies liegt daran, in secondCall Sie diese beiden als Argumente an Meteor.Error sind vorbei, die als Argumente nimmt error, reason und details:

https://github.com/meteor/meteor/blob/devel/packages/meteor/errors.js

Um diese durchlaufen, müssen Sie zu ändern firstCall diese Eigenschaften zu verwenden:

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); 
    } 
} 

ich bin nicht einmal sicher, dass Sie es aufteilen müssen bis in zwei Forderungen nach Modularität, wie Sie nur normale Javascript-Funktionen verwenden können. Aber wir können das anderswo diskutieren.

+0

Auch dies scheint nicht die korrekte Information aus dem Fehler zurückzugeben. Mein Beispiel oben reicht nicht aus, um das Problem zu erklären.Ich habe meine ganze firstCall in einen Versuch Catch gewickelt, aber wenn der Fehler ausgelöst wird, scheint der Code weiterhin ausgeführt werden, was einen anderen Fehler verursacht, und das ist, was von FirstCall an den Client zurückgegeben wird. – JoshJoe

+0

Rufen Sie 'secondCall' synchron an? Siehe meine Überarbeitung. –

+0

Ich habe es nicht synchron aufgerufen. Das hat es behoben, aber ich denke, dass es sicherlich einen besseren Weg geben muss, den Fehler zum Client zu bringen. Ich bin mir sicher, dass ich das nicht so gut mache. Vielen Dank – JoshJoe

0

ich einige Dinge hier zu erwähnen:

  1. Async-Funktion löst keine Exceptions aus (außer dass Sie sie mithilfe von Meteor._wrapAsync synchronisieren, wie ich später erklären werde), sie geben den Fehler auf andere Weise zurück (als erstes Argument im NodeJS-Callback) -Stil). Dies gilt sowohl für Meteor.call als auch für Ihre doSomeAsyncThing.
  2. Ich kann nicht den Vorteil der Verwendung von Meteor.call auf dem Server sehen. Meteor.call soll Server-Methoden vom Client aufrufen. In diesem Fall können Sie YourObj.secondCall von innerhalb firstCall anrufen.
  3. Wenn Sie innerhalb eines Callbacks etwas zurückgeben (wie Sie es in firstCall tun), hat das keine Auswirkung. Sie möchten, dass Ihr Async-Code als Sync-Code funktioniert, daher empfehle ich die Verwendung von Meteor._wrapAsync, was sehr gut erklärt ist here.
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); 
    } 

hoffe, das hilft: Also, ich würde Server-Seite ein bisschen anders implementieren!

+0

Ok, ich habe die Frage aktualisiert, um die versprochene asynchrone Funktion anzuzeigen, die ich verwende. Ich kann _wrapAsync nicht verwenden, weil es nicht mit Versprechen funktioniert. Außerdem bemerkte ich, dass ich ein paar verpasste. Also legte ich die da hin, wo sie hingehören. Ich habe meine Methodenaufrufe in einer anderen Datei und deshalb habe ich eine andere Meteor.call gemacht. Ich nehme an, ich könnte stattdessen eine Funktion verwenden, aber ich versuche, meine Methoden zu multiplizieren und ich möchte sie aus vielen verschiedenen Dateien aufrufen können. – JoshJoe

Verwandte Themen