slackapi / node-slack-sdk

Slack Developer Kit for Node.js
https://slack.dev/node-slack-sdk
MIT License
3.27k stars 661 forks source link

app crashed randomly #152

Closed benzmuircroft closed 8 years ago

benzmuircroft commented 8 years ago

My app was running in another tab when it crashed. I am the only user. and there were no changes to my slack team (no new messages or activity of any kind).

it looks like something happened on line 178 of client.js which caused async.js to throw an error

/var/sentora/hostdata/zadmin/public_html/node_modules/@slack/client/node_modules/async/lib/async.js:43
        if (fn === null) throw new Error("Callback was already called.");
                         ^

Error: Callback was already called.
at        /var/sentora/hostdata/zadmin/public_html/node_modules/@slack/client/node_modules/async/lib/async.js:43:36
at handleTransportResponse (/var/sentora/hostdata/zadmin/public_html/node_modules/@slack/client/lib/clients/client.js:178:5)
at Request.handleRequestTranportRes (/var/sentora/hostdata/zadmin/public_html/node_modules/@slack/client/lib/clients/transports/request.js:20:5)
at Request.wrapper [as _callback] (/var/sentora/hostdata/zadmin/public_html/node_modules/@slack/client/node_modules/lodash/index.js:3592:19)
at Request.self.callback (/var/sentora/hostdata/zadmin/public_html/node_modules/@slack/client/node_modules/request/request.js:199:22)
at emitTwo (events.js:87:13)
at Request.emit (events.js:172:7)
at Request.<anonymous> (/var/sentora/hostdata/zadmin/public_html/node_modules/@slack/client/node_modules/request/request.js:1036:10)
at emitOne (events.js:82:20)
at Request.emit (events.js:169:7)
[root@panel ~]# node /var/sentora/hostdata/zadmin/public_html/private_js/N.yt.js 

here is my code (one instance per user)

    var ⵌ={//slack per user
            RtmClient:require('@slack/client').RtmClient
        ,   RTM_EVENTS:require('@slack/client').RTM_EVENTS
        ,   WebClient:require('@slack/client/lib/clients/web/client')
        ,   t:'xoxp-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
        ,   rtm:undefined
        ,   web:undefined
        ,   cid:undefined
        ,   find:function(){
                ⵌ.rtm=new ⵌ.RtmClient(ⵌ.t,{logLevel:'none'});
                ⵌ.web=new ⵌ.WebClient(ⵌ.t);
                ⵌ.rtm.start();
                ⵌ.web.channels.list(function(e,l){
                    if(!e&&l.ok){
                        for(var i=0;i<l.channels.length;++i){
                            if(l.channels[i].name=='?-'+U.username){
                                ⵌ.cid=l.channels[i].id;break;//found the users channel
                                }}}
                    if(ⵌ.cid){
                        ⵌ.web.channels.history(ⵌ.cid,{},function(e,h){
                            h=h.messages.reverse();
                            var history=[];
                            for(var i=0;i<h.length;++i){
                                if((h[i].subtype=='bot_message'||!h[i].subtype)&&h[i].type=='message'){
                                    history.push({
                                        username:h[i].username.replace('?-','')||'yt'
                                    ,   text:h[i].text
                                        });}}
                            s[1][NULL].WIRE('svr:slack:uzr',history);//give the client the history of chat
                            G.SLACK[ⵌ.cid]={uid:U.id,'suid':s[1].uid};//save the client stuff
                            s[1][NULL].WHEN['uzr:slack:svr']=function(d){//client wants to post a message
                                ⵌ.msg=d;//there is a message so it will post
                                ⵌ.say();
                                };
                            });}});}
        ,   say:function(){//console.log('posing');
                function created(ch){
                    if(ch.name=='?-'+U.username){
                        ⵌ.cid=ch.channel.id;
                        ⵌ.rtm.on(ⵌ.RTM_EVENTS.CHANNEL_CREATED,null);
                        }
                    return;
                    }
                function post(){
                    ⵌ.web.chat.postMessage(ⵌ.cid,ⵌ.msg,{username:U.username,icon_url:ⵌ.profileimg,account_id:U.id},function(){//console.log('posted!!');
                        ⵌ.msg=undefined;
                        });}
                if(ⵌ.msg){
                    if(!ⵌ.cid){
                        ⵌ.rtm.on(ⵌ.RTM_EVENTS.CHANNEL_CREATED,created);
                        ⵌ.web.channels.create('?-'+U.username,function(){post();});}
                    else{post();}
                    }
                return;
                }
        ,   profileimg:'defaultuser.png'//todo get real image
        ,   msg:undefined//'my awsome message!'
            };

here is my code (only one instance to listen for all messages for my team)

var ⵌ={//slack globally listening
    RtmClient:require('@slack/client').RtmClient
,   RTM_EVENTS:require('@slack/client').RTM_EVENTS
,   t:'xoxp-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
,   rtm:undefined
,   route:function(){
        ⵌ.rtm=new ⵌ.RtmClient(ⵌ.t,{logLevel:'none'});
        ⵌ.rtm.start();
        ⵌ.rtm.on(ⵌ.RTM_EVENTS.MESSAGE,function(m){// Listens to all `message` events from the team
            console.log('G slack',m);
            if((m.subtype=='bot_message'||!m.subtype)&&m.type=='message'){
                var msg={username:m.username||'yt',text:m.text};
                for(var k in G.R[G.SLACK[m.channel].uid]){//find the user they are some where in the saved G global object
                    if(G.R[G.SLACK[m.channel].uid][k].readyState==1){
                        try{
                        G.R[G.SLACK[m.channel].uid][k].send('ʲ'+JSON.stringify({f:'glb:slack:uzr',d:msg}));//relay the message to the user
                        }
                    catch(e){
                        console.log(e);
                        }}}
            }});
        return;
        }};
ⵌ.route();

my code works nice plugged into slack but, why did that random crash happen?

clavin commented 8 years ago

Just to add some info to this issue, it seems that queueCb (in /lib/clients/client.js, the _callTransport function) is being called twice (at least). The error being thrown is automatically thrown by the async module.

ghost commented 8 years ago

Thanks, I'll take a look at what's happening this evening. I've seen this issue before with the way the requeue logic works, so it maybe a bug in the way that works.

ghost commented 8 years ago

Ok, I'm fairly sure that you hit a retry limit with the number of calls that you were making and that there's a bug in the way the current request retry logic works. I'm tweaking the way the retry logic works now.

ghost commented 8 years ago

Try using the 2.0.6 version and see if this still happens.