import pprint
import logging
logger = logging.getLogger(__name__)
[docs]class SpotifyError(Exception):
"""
Base error class for ApiError and AuthError
"""
def _build_super_msg(self, msg, http_res, http_req, e):
if not http_req and not http_res and not e:
return msg
elif (
getattr(http_res, "status_code", None) == 400 and http_req
): # If bad request or not found, show url and data
body = http_req.data or http_req.json
return "\nError msg: {}\nHTTP Error: 400-Bad request\nRequest URL: {}\nRequest body: {}\nRequest headers: {}".format(
msg,
http_req.url,
pprint.pformat(body),
pprint.pformat(http_req.headers),
)
elif getattr(http_res, "status_code", None) == 401 and http_req:
return "\nError msg: {}\nHTTP Error: {}.\nRequest headers: {}".format(
msg, http_res.status_code, pprint.pformat(http_req.headers)
)
elif getattr(http_res, "status_code", None) == 403 and http_req:
body = http_req.data or http_req.json
return "\nError msg: {}\nHTTP Error: 403-Forbidden\nRequest URL: {}\nRequest body: {}\nRequest headers: {}".format(
msg,
http_req.url,
pprint.pformat(body),
pprint.pformat(http_req.headers),
)
elif getattr(http_res, "status_code", None) == 404 and http_req:
body = http_req.data or http_req.json
return "\nError msg: {}\nHTTP Error: 404-Resource not found\nRequest URL: {}\nRequest body: {}".format(
msg, http_req.url, pprint.pformat(body)
)
return pprint.pformat(
{
"msg": msg,
"http_response": http_res.__dict__,
"http_request": http_req.__dict__,
"original exception": e,
}
)
[docs]class ApiError(SpotifyError):
"""
Almost any HTTP error other than 401 raises this error
https://developer.spotify.com/documentation/web-api/#response-schema // regular error object
Attributes:
msg (str): Error msg returned from Spotify
http_response: Full HTTP response
http_request: Full HTTP request that caused this error
code (int): HTTP status code
"""
def __init__(self, msg, http_response=None, http_request=None, e=None):
self.msg = msg
self.http_response = http_response
self.http_request = http_request
self.code = getattr(http_response, "status_code", None)
super_msg = self._build_super_msg(msg, http_response, http_request, e)
logger.error(super_msg)
super(ApiError, self).__init__(super_msg)
[docs]class AuthError(SpotifyError):
""" Raised when a 401 or any Authentication error is encountered
https://developer.spotify.com/documentation/web-api/#response-schema // authentication error object
Attributes:
msg (str): Error msg returned from Spotify
http_response: Full HTTP response
http_request: Full HTTP request that caused this error
code (int): HTTP status code
"""
def __init__(self, msg, http_response=None, http_request=None, e=None):
self.msg = msg
self.http_response = http_response
self.http_request = http_request
self.code = getattr(http_response, "status_code", None)
super_msg = self._build_super_msg(msg, http_response, http_request, e)
logger.error(super_msg)
super(AuthError, self).__init__(super_msg)
class _TooManyRequests(ApiError):
pass