From fc1d134685578bdc255b5022ccf25a0e9127549d Mon Sep 17 00:00:00 2001 From: Shivam Gera Date: Sun, 28 Jan 2018 01:51:49 +0530 Subject: [PATCH] api: Use custom exceptions in API client. This removes the use of RuntimeError, and replaces it with a custom error class called ZulipError. In a few places, we use a subclass to make it easier for code to interact with the error type. --- zulip/tests/test_default_arguments.py | 4 +-- zulip/zulip/__init__.py | 38 ++++++++++++++++----------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/zulip/tests/test_default_arguments.py b/zulip/tests/test_default_arguments.py index 60a1d79..0b983a8 100755 --- a/zulip/tests/test_default_arguments.py +++ b/zulip/tests/test_default_arguments.py @@ -7,7 +7,7 @@ import unittest import zulip from unittest import TestCase - +from zulip import ZulipError if six.PY2: from mock import patch else: @@ -38,7 +38,7 @@ Zulip API configuration: parser = zulip.add_default_arguments(argparse.ArgumentParser(usage="lorem ipsum")) test_path = '~/zuliprc' args = parser.parse_args(['--config-file', test_path]) - with self.assertRaises(RuntimeError) as cm: + with self.assertRaises(ZulipError) as cm: zulip.init_from_options(args) expanded_test_path = os.path.abspath(os.path.expanduser(test_path)) self.assertEqual(str(cm.exception), 'api_key or email not specified and ' diff --git a/zulip/zulip/__init__.py b/zulip/zulip/__init__.py index bcf172c..ac9d5a0 100644 --- a/zulip/zulip/__init__.py +++ b/zulip/zulip/__init__.py @@ -267,13 +267,19 @@ def get_default_config_filename(): config_file = os.path.join(os.environ["HOME"], ".zuliprc") if (not os.path.exists(config_file) and os.path.exists(os.path.join(os.environ["HOME"], ".humbugrc"))): - raise RuntimeError("The Zulip API configuration file is now ~/.zuliprc; please run:\n\n" - " mv ~/.humbugrc ~/.zuliprc\n") + raise ZulipError("The Zulip API configuration file is now ~/.zuliprc; please run:\n\n" + " mv ~/.humbugrc ~/.zuliprc\n") return config_file class ZulipError(Exception): pass +class ConfigNotFoundError(ZulipError): + pass + +class MissingURLError(ZulipError): + pass + class Client(object): def __init__(self, email=None, api_key=None, config_file=None, verbose=False, retry_on_errors=True, @@ -331,11 +337,11 @@ class Client(object): elif insecure_setting == "false": insecure = False else: - raise RuntimeError("insecure is set to '%s', it must be 'true' or 'false' if it is used in %s" - % (insecure_setting, config_file)) + raise ZulipError("insecure is set to '%s', it must be 'true' or 'false' if it is used in %s" + % (insecure_setting, config_file)) elif None in (api_key, email): - raise RuntimeError("api_key or email not specified and file %s does not exist" - % (config_file,)) + raise ConfigNotFoundError("api_key or email not specified and file %s does not exist" + % (config_file,)) assert(api_key is not None and email is not None) self.api_key = api_key @@ -350,7 +356,7 @@ class Client(object): site = site.rstrip("/") self.base_url = site else: - raise RuntimeError("Missing Zulip server URL; specify via --site or ~/.zuliprc.") + raise MissingURLError("Missing Zulip server URL; specify via --site or ~/.zuliprc.") if not self.base_url.endswith("/api"): self.base_url += "/api" @@ -362,8 +368,8 @@ class Client(object): self.tls_verification = False # type: Union[bool, str] elif cert_bundle is not None: if not os.path.isfile(cert_bundle): - raise RuntimeError("tls bundle '%s' does not exist" - % (cert_bundle,)) + raise ConfigNotFoundError("tls bundle '%s' does not exist" + % (cert_bundle,)) self.tls_verification = cert_bundle else: # Default behavior: verify against system CA certificates @@ -371,16 +377,16 @@ class Client(object): if client_cert is None: if client_cert_key is not None: - raise RuntimeError("client cert key '%s' specified, but no client cert public part provided" - % (client_cert_key,)) + raise ConfigNotFoundError("client cert key '%s' specified, but no client cert public part provided" + % (client_cert_key,)) else: # we have a client cert if not os.path.isfile(client_cert): - raise RuntimeError("client cert '%s' does not exist" - % (client_cert,)) + raise ConfigNotFoundError("client cert '%s' does not exist" + % (client_cert,)) if client_cert_key is not None: if not os.path.isfile(client_cert_key): - raise RuntimeError("client cert key '%s' does not exist" - % (client_cert_key,)) + raise ConfigNotFoundError("client cert key '%s' does not exist" + % (client_cert_key,)) self.client_cert = client_cert self.client_cert_key = client_cert_key @@ -398,7 +404,7 @@ class Client(object): # Build a client cert object for requests if self.client_cert_key is not None: - assert(self.client_cert is not None) # Otherwise RuntimeError near end of __init__ + assert(self.client_cert is not None) # Otherwise ZulipError near end of __init__ client_cert = (self.client_cert, self.client_cert_key) # type: Union[None, str, Tuple[str, str]] else: client_cert = self.client_cert