Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Error handling rework #38

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 24 additions & 28 deletions appnexus/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import requests

from appnexus.cursor import Cursor
from appnexus.exceptions import (AppNexusException, BadCredentials, NoAuth,
RateExceeded)
from appnexus.exceptions import AppNexusException, BadCredentials
from appnexus.utils import normalize_service_name

try:
Expand All @@ -22,8 +21,6 @@ class AppNexusClient(object):
"""Represents an active connection to the AppNexus API"""
url = "https://api.appnexus.com/"
test_url = "https://api-test.appnexus.com/"
error_codes = {"RATE_EXCEEDED": RateExceeded}
error_ids = {"NOAUTH": NoAuth}

def __init__(self, username=None, password=None, test=False,
representation=None, token_file=None):
Expand Down Expand Up @@ -77,6 +74,7 @@ def _send(self, send_method, service_name, data=None, **kwargs):
"""
valid_response = False
raw = kwargs.pop("raw", False)
custom_exception_handlers = kwargs.pop("custom_exception_handlers")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
custom_exception_handlers = kwargs.pop("custom_exception_handlers")
custom_exception_handlers = kwargs.pop("custom_exception_handlers", None)


while not valid_response:
headers = dict(Authorization=self.token)
Expand All @@ -97,10 +95,9 @@ def _send(self, send_method, service_name, data=None, **kwargs):

try:
self.check_errors(response, response_data)
except RateExceeded:
self._handle_rate_exceeded(response)
except NoAuth:
self.update_token()
except AppNexusException as e:
self._exception_handler(e, response, response_data,
custom_exception_handlers)
else:
valid_response = True
if raw:
Expand All @@ -113,33 +110,32 @@ def update_token(self):
if None in self.credentials.values():
raise RuntimeError("You must provide an username and a password")
credentials = dict(auth=self.credentials)
url = self.test_url if self.test else self.url
response = requests.post(url + "auth",
json=credentials)
data = response.json()["response"]
if "error_id" in data and data["error_id"] == "NOAUTH":
response = self.create("auth", credentials)
if "error_id" in response and response["error_id"] == "NOAUTH":
raise BadCredentials()
if "error_code" in data and data["error_code"] == "RATE_EXCEEDED":
time.sleep(150)
return
if "error_code" in data or "error_id" in data:
raise AppNexusException(response)
self.token = data["token"]
self.token = response["token"]
self.save_token()
return self.token

def check_errors(self, response, data):
"""Check for errors and raise an appropriate error if needed"""
if "error_id" in data:
error_id = data["error_id"]
if error_id in self.error_ids:
raise self.error_ids[error_id](response)
if "error_code" in data:
error_code = data["error_code"]
if error_code in self.error_codes:
raise self.error_codes[error_code](response)
if "error_code" in data or "error_id" in data:
raise AppNexusException(response)
raise type(data["error_id"], (AppNexusException,), {})(response)
Copy link
Contributor

@ramnes ramnes Jul 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to create a new type if we catch it right after. Let's remove that method and check the "error_id" directly in an handle_errors method.


def _exception_handler(self, exception,
response, data,
custom_handler=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handlers*

_default_handler = {
"NOAUTH": self.update_token,
"RATE_EXCEEDED": self._handle_rate_exceeded,
}
if custom_handler and isinstance(dict, custom_handler):
_default_handler.update(**custom_handler)
exception_name = type(exception).__name__
if exception_name in _default_handler:
_default_handler[exception_name]()
else:
raise

def get(self, service_name, **kwargs):
"""Retrieve data from AppNexus API"""
Expand Down
12 changes: 1 addition & 11 deletions appnexus/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,11 @@ def __str__(self):
return "{}: {}".format(error_name, description_error)


class RateExceeded(AppNexusException):
"""Exception raised when the client reached the rate limit"""
pass


class NoAuth(AppNexusException):
"""Exception raised when the client's authentication expired"""
pass


class BadCredentials(AppNexusException):
"""Exception raised when wrong credentials are provided"""

def __str__(self):
return "You provided bad credentials for the AppNexus API"


__all__ = ["AppNexusException", "RateExceeded", "NoAuth", "BadCredentials"]
__all__ = ["AppNexusException", "BadCredentials"]