igauravsehrawat
igauravsehrawat

Reputation: 3954

How can I avoid `socket is already closed ` error in python while using slack api?

I have the following script to monitor a slack channel. My script runs fine for weeks but some time I get an Exception caught which is printed as socket is already closed. I am unable to find resource on this error but it never reconnects. I keep getting this error forever once it appears.

I want to understand why it's happening and what's the solution for it?

import os
import time
from slackclient import SlackClient

# constants
BOT_ID = os.environ["LOUD_BOT_ID"]
LOUD_BOT_TOKEN = os.environ["LOUD_BOT_TOKEN"]
AT_BOT = "<@" + BOT_ID + ">"

slack_client = SlackClient(os.environ["LOUD_BOT_TOKEN"])

def parse_slack_output(rtm_read_output):
    output_list = rtm_read_output
    if output_list and len(output_list) > 0:
        for output in output_list:
            if output and "text" in output and AT_BOT in output["text"]:
                return (
                    output["text"].split(AT_BOT)[1].strip(),
                    output["channel"],
                    output["user"]
                )
    return None, None, None

if __name__ == "__main__":
    READ_WEBSOCKET_DELAY = 1
    if slack_client.rtm_connect():
        print "Bot is up and running..."
        while True:
            try:
                message, channel, sender_user_id = parse_slack_output(
                    slack_client.rtm_read()
                )
                print message, channel, sender_user_id
                time.sleep(READ_WEBSOCKET_DELAY)
            except Exception as e:
                print e
                time.sleep(READ_WEBSOCKET_DELAY)
    else:
        print "Couldn't connect bot, please check bot's token and ID"

Thanks

Upvotes: 0

Views: 4189

Answers (1)

lixuanbin
lixuanbin

Reputation: 51

You have to do it in a try-catch-reconnect way:

if __name__ == "__main__":
    reload(sys)
    sys.setdefaultencoding('utf-8')
    READ_WEBSOCKET_DELAY = 1
    if slack_client.rtm_connect():
        print("jfbot connected and running!")
        while True:
            try:
                command, channel = parse_slack_output(slack_client.rtm_read())
                if command and channel:
                    handle_command(command, channel)
                time.sleep(READ_WEBSOCKET_DELAY)
            except WebSocketConnectionClosedException as e:
                print e
                print 'Caught websocket disconnect, reconnecting...'
                time.sleep(READ_WEBSOCKET_DELAY)
                slack_client.rtm_connect()
            except Exception, e:
                print e
                time.sleep(READ_WEBSOCKET_DELAY)
    else:
        print("Connection failed. Invalid Slack token or bot ID?")

Upvotes: 5

Related Questions