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:
parent
a19278da65
commit
043d963a99
|
@ -271,6 +271,9 @@ def get_default_config_filename():
|
||||||
" mv ~/.humbugrc ~/.zuliprc\n")
|
" mv ~/.humbugrc ~/.zuliprc\n")
|
||||||
return config_file
|
return config_file
|
||||||
|
|
||||||
|
class ZulipError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
class Client(object):
|
class Client(object):
|
||||||
def __init__(self, email=None, api_key=None, config_file=None,
|
def __init__(self, email=None, api_key=None, config_file=None,
|
||||||
verbose=False, retry_on_errors=True,
|
verbose=False, retry_on_errors=True,
|
||||||
|
@ -382,6 +385,8 @@ class Client(object):
|
||||||
|
|
||||||
self.session = None # type: Union[None, requests.Session]
|
self.session = None # type: Union[None, requests.Session]
|
||||||
|
|
||||||
|
self.has_connected = False
|
||||||
|
|
||||||
def ensure_session(self):
|
def ensure_session(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
|
|
||||||
|
@ -507,6 +512,8 @@ class Client(object):
|
||||||
timeout=request_timeout,
|
timeout=request_timeout,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
|
self.has_connected = True
|
||||||
|
|
||||||
# On 50x errors, try again after a short sleep
|
# On 50x errors, try again after a short sleep
|
||||||
if str(res.status_code).startswith('5'):
|
if str(res.status_code).startswith('5'):
|
||||||
if error_retry(" (server %s)" % (res.status_code,)):
|
if error_retry(" (server %s)" % (res.status_code,)):
|
||||||
|
@ -528,6 +535,13 @@ class Client(object):
|
||||||
return {'msg': "Connection error:\n%s" % traceback.format_exc(),
|
return {'msg': "Connection error:\n%s" % traceback.format_exc(),
|
||||||
"result": "connection-error"}
|
"result": "connection-error"}
|
||||||
except requests.exceptions.ConnectionError:
|
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(""):
|
if error_retry(""):
|
||||||
continue
|
continue
|
||||||
end_error_retry(False)
|
end_error_retry(False)
|
||||||
|
|
|
@ -17,7 +17,7 @@ if False:
|
||||||
from typing import Any, Optional, List, Dict, IO, Text, Set
|
from typing import Any, Optional, List, Dict, IO, Text, Set
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
|
|
||||||
from zulip import Client
|
from zulip import Client, ZulipError
|
||||||
|
|
||||||
def exit_gracefully(signum, frame):
|
def exit_gracefully(signum, frame):
|
||||||
# type: (int, Optional[Any]) -> None
|
# type: (int, Optional[Any]) -> None
|
||||||
|
@ -95,7 +95,17 @@ class ExternalBotHandler(object):
|
||||||
def __init__(self, client, root_dir, bot_details={}):
|
def __init__(self, client, root_dir, bot_details={}):
|
||||||
# type: (Client, str, Dict[str, Any]) -> None
|
# type: (Client, str, Dict[str, Any]) -> None
|
||||||
# Only expose a subset of our Client's functionality
|
# 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._rate_limit = RateLimit(20, 5)
|
||||||
self._client = client
|
self._client = client
|
||||||
self._root_dir = root_dir
|
self._root_dir = root_dir
|
||||||
|
|
Loading…
Reference in a new issue