Skip to content

Commit

Permalink
WIP: Error handling rework
Browse files Browse the repository at this point in the history
  • Loading branch information
rambobinator committed Jun 26, 2019
1 parent d6a8134 commit a98ef9c
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 39 deletions.
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")

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)

def _exception_handler(self, exception,
response, data,
custom_handler=None):
_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"]

1 comment on commit a98ef9c

@rambobinator
Copy link
Collaborator Author

@rambobinator rambobinator commented on a98ef9c Jun 27, 2019

Choose a reason for hiding this comment

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

@ramnes any thoughts about this ?
The goal is to allow callback on specific error.

Please sign in to comment.