tutorial test instalar examples como apps meteor

test - Error: el código Meteor siempre debe ejecutarse dentro de una Fibra



meteor tutorial (2)

Estoy utilizando Stripe para pagos en mi aplicación. Quiero crear un documento de recibo en mi propia base de datos después de una transacción exitosa.

Mi código:

Meteor.methods({ makePurchase: function(tabId, token) { check(tabId, String); tab = Tabs.findOne(tabId); Stripe.charges.create({ amount: tab.price, currency: "USD", card: token.id }, function (error, result) { console.log(result); if (error) { console.log(''makePurchaseError: '' + error); return error; } Purchases.insert({ sellerId: tab.userId, tabId: tab._id, price: tab.price }, function(error, result) { if (error) { console.log(''InsertionError: '' + error); return error; } }); }); } });

Sin embargo, este código devuelve un error:

Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.

No estoy familiarizado con Fibras, ¿alguna idea de por qué esto es?


El problema aquí es que la función de devolución de llamada que se pasa a Stripe.charges.create se llama de forma asíncrona (por supuesto), por lo que está sucediendo fuera de la actual Meteor''s Fiber .

Una forma de solucionarlo es crear su propia Fiber , pero lo más fácil que puede hacer es envolver la devolución de llamada con Meteor.bindEnvironment , así que básicamente

Stripe.charges.create({ // ... }, Meteor.bindEnvironment(function (error, result) { // ... }));

Editar

Como se sugiere en la otra respuesta, otro y, probablemente, mejor patrón a seguir aquí es el uso del método de ayuda Meteor.wrapAsync (ver docs ), que básicamente le permite convertir cualquier método asíncrono en una función que tenga en cuenta la fibra y se pueda usar sincrónicamente.

En su caso específico, una solución equivalente sería escribir:

let result; try { result = Meteor.wrapAsync(Stripe.charges.create, Stripe.charges)({ /* ... */ }); } catch(error) { // ... }

Tenga en cuenta el segundo argumento pasado a Meteor.wrapAsync . Es para asegurarse de que el Stripe.charges.create original reciba el contexto adecuado, en caso de que sea necesario.