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.
MODIFY
zulip/tests/test_default_arguments.py
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 '

MODIFY
zulip/zulip/__init__.py
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"
+ 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,10 +337,10 @@ 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"
+ 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"
+ 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)
@@ -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,7 +368,7 @@ 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"
+ raise ConfigNotFoundError("tls bundle '%s' does not exist"
% (cert_bundle,))
self.tls_verification = cert_bundle
else:
@@ -371,15 +377,15 @@ 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"
+ 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"
+ 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"
+ 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

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.