From 043d963a994d5c39d5984056f5d9a54ea6138460 Mon Sep 17 00:00:00 2001 From: Steve Howell Date: Tue, 21 Nov 2017 14:21:04 -0800 Subject: [PATCH] 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. --- zulip/zulip/__init__.py | 14 ++++++++++++++ zulip_bots/zulip_bots/lib.py | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/zulip/zulip/__init__.py b/zulip/zulip/__init__.py index fc9cbf3..27efab6 100644 --- a/zulip/zulip/__init__.py +++ b/zulip/zulip/__init__.py @@ -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) diff --git a/zulip_bots/zulip_bots/lib.py b/zulip_bots/zulip_bots/lib.py index b8550e5..12eca3b 100644 --- a/zulip_bots/zulip_bots/lib.py +++ b/zulip_bots/zulip_bots/lib.py @@ -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