Fail fast for bad connections with the API and bots.

The API has aggressive retry logic for connecting to a
server, which may make sense for situation where you have
connection blips or server restarts.

When you're first connecting to the API, however, connection
failures are almost certainly a sign of misconfiguration, so
now we fail fast.

The bot lib takes advantage of this API change by catching the
ZulipError exception and exiting gracefully.
This commit is contained in:
Steve Howell 2017-11-21 14:21:04 -08:00
parent a19278da65
commit 043d963a99
2 changed files with 26 additions and 2 deletions

View file

@ -271,6 +271,9 @@ def get_default_config_filename():
" mv ~/.humbugrc ~/.zuliprc\n")
return config_file
class ZulipError(Exception):
pass
class Client(object):
def __init__(self, email=None, api_key=None, config_file=None,
verbose=False, retry_on_errors=True,
@ -382,6 +385,8 @@ class Client(object):
self.session = None # type: Union[None, requests.Session]
self.has_connected = False
def ensure_session(self):
# type: () -> None
@ -507,6 +512,8 @@ class Client(object):
timeout=request_timeout,
**kwargs)
self.has_connected = True
# On 50x errors, try again after a short sleep
if str(res.status_code).startswith('5'):
if error_retry(" (server %s)" % (res.status_code,)):
@ -528,6 +535,13 @@ class Client(object):
return {'msg': "Connection error:\n%s" % traceback.format_exc(),
"result": "connection-error"}
except requests.exceptions.ConnectionError:
if not self.has_connected:
# If we have never successfully connected to the server, don't
# go into retry logic, because the most likely scenario here is
# that somebody just hasn't started their server, or they passed
# in an invalid site.
raise ZulipError('cannot connect to server ' + self.base_url)
if error_retry(""):
continue
end_error_retry(False)

View file

@ -17,7 +17,7 @@ if False:
from typing import Any, Optional, List, Dict, IO, Text, Set
from types import ModuleType
from zulip import Client
from zulip import Client, ZulipError
def exit_gracefully(signum, frame):
# type: (int, Optional[Any]) -> None
@ -95,7 +95,17 @@ class ExternalBotHandler(object):
def __init__(self, client, root_dir, bot_details={}):
# type: (Client, str, Dict[str, Any]) -> None
# Only expose a subset of our Client's functionality
user_profile = client.get_profile()
try:
user_profile = client.get_profile()
except ZulipError as e:
print('''
ERROR: {}
Have you not started the server?
Or did you mis-specify the URL?
'''.format(e))
sys.exit(1)
self._rate_limit = RateLimit(20, 5)
self._client = client
self._root_dir = root_dir