How to publish an asynchronous error?


#1

On server:

Meteor.methods({
    sendSms: function(phone, body) {
        if (Meteor.isServer)
            sendSms(phone, body, function(error, data) {
               ....................
            });
    }
});

On client:

var status = Meteor.call("sendSms", phone, "hello", function(error, data) {
   if (error) 
         .....
}

How does server notify client of an error?


#2

I found that I am supposed to throw a Meteor.Error. So my code now is like this:

on server:

twilio.sendSMS({
to: phone,
body: body
}, function(error, response) {
if (error) {

        console.log("twilio error#####", error.message, response);
        throw new Meteor.Error("mSendSms", error.message);
        
    }
});

on client:

    Meteor.call("mSendSms", phone, "That's more like it", function(err, data) {
        console.log("Called mSendSms", err, data);
    });

On server, I get

Exception in callback of async function: Error: The
'To' number 111111 is not a valid phone number. [mSendSms]
     at js/server/sms.js:38:19
     at runWithEnvironment (packages/meteor/dynamics_
nodejs.js:108:1)

On client, I get

  Called mSendSms undefined undefined

When I though Meteor.Error directly from method, it does get passed to client; but when I throw it from an asynchronous callback of a function called by my method, it does not get passed. What am I doing wrong?


#3

You should wrap your async functions with Meteor.wrapAsync or use Fibers directly. Moreover you can use packages that allow call Meteor.methods in common callback-style mode


#4

I spent a lot of time trying and am getting weird exceptions with wrapAsync:

I20151019-22:07:16.358(-7)? ~~~EXCEPTION!!! { stack: [Getter] } [object Object]
I20151019-22:07:16.359(-7)?     at Object.Future.wait (C:\Users\I\AppData\Local\
.meteor\packages\meteor-tool\1.1.9\mt-os.windows.x86_32\dev_bundle\server-lib\no
de_modules\fibers\future.js:398:15)
I20151019-22:07:16.359(-7)?     at packages/meteor/helpers.js:119:1
I20151019-22:07:16.359(-7)?     at sendSms (js/server/sms.js:32:18)
I20151019-22:07:16.360(-7)?     at packages/meteor/helpers.js:118:1
I20151019-22:07:16.360(-7)?     at [object Object].Meteor.methods.mSendSms (js/m
ethods.js:33:30)
I20151019-22:07:16.360(-7)?     at livedata_server.js:708:19
I20151019-22:07:16.360(-7)?     at maybeAuditArgumentChecks (livedata_server.js:
1692:12)
I20151019-22:07:16.361(-7)?     at [object Object]._.extend.withValue (packages/
meteor/dynamics_nodejs.js:56:1)
I20151019-22:07:16.361(-7)?     at livedata_server.js:706:40
I20151019-22:07:16.361(-7)?     at [object Object]._.extend.withValue (packages/
meteor/dynamics_nodejs.js:56:1)

And just now, my Webstorm stopped breaking on breakpoints, so no way to debug this.

Maybe someone could point me out to the correct use of wrapAsync?


#5

Hi, I think your logic should be like:

Meteor.methods
  sendSms: (phone, text) ->
    check(phone, String)
    check(text, String)
    wrappedCall = Meteor.wrapAsync(twillio.sendSMS)
    return wrappedCall({to: phone, body: text})

#6

That’s exactly what I am doing I believe.

What’s check()?


#7

http://docs.meteor.com/#/full/check


#8

Turns out, on 1.2 you have to do

meteor add check

I don’t think it’s documented?


#9

Not explicitly but there is:

 The check package includes....

which tells you it’s a package. Since 1.2 you need to include what you use so yes you re right not explicitly but it’s there. Might be good maybe for documentation to have the same block at the top as atmosphere:

https://atmospherejs.com/meteor/check

$ meteor add check