Module pyControl4.error_handling
Handles errors recieved from the Control4 API.
Expand source code
"""Handles errors recieved from the Control4 API."""
import json
import xmltodict
class C4Exception(Exception):
"""Base error for pyControl4."""
def __init__(self, message):
self.message = message
class NotFound(C4Exception):
"""Raised when a 404 response is recieved from the Control4 API.
Occurs when the requested controller, etc. could not be found."""
class Unauthorized(C4Exception):
"""Raised when unauthorized, but no other recognized details are provided.
Occurs when token is invalid."""
class BadCredentials(Unauthorized):
"""Raised when provided credentials are incorrect."""
class BadToken(Unauthorized):
"""Raised when director bearer token is invalid."""
class InvalidCategory(C4Exception):
"""Raised when an invalid category is provided when calling
`pyControl4.director.C4Director.getAllItemsByCategory`."""
ERROR_CODES = {"401": Unauthorized, "404": NotFound}
ERROR_DETAILS = {
"Permission denied Bad credentials": BadCredentials,
}
DIRECTOR_ERRORS = {"Unauthorized": Unauthorized, "Invalid category": InvalidCategory}
DIRECTOR_ERROR_DETAILS = {"Expired or invalid token": BadToken}
async def __checkResponseFormat(response_text: str):
"""Known Control4 authentication API error message formats:
```json
{
"C4ErrorResponse": {
"code": 401,
"details": "Permission denied Bad credentials",
"message": "Permission denied",
"subCode": 0
}
}
```
```json
{
"code": 404,
"details": "Account with id:000000 not found in DB",
"message": "Account not found",
"subCode": 0
}```
```xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<C4ErrorResponse>
<code>401</code>
<details></details>
<message>Permission denied</message>
<subCode>0</subCode>
</C4ErrorResponse>
```
Known Control4 director error message formats:
```json
{
"error": "Unauthorized",
"details": "Expired or invalid token"
}
```
"""
if response_text.startswith("<"):
return "XML"
return "JSON"
async def checkResponseForError(response_text: str):
"""Checks a string response from the Control4 API for error codes.
Parameters:
`response_text` - JSON or XML response from Control4, as a string.
"""
if await __checkResponseFormat(response_text) == "JSON":
dictionary = json.loads(response_text)
elif await __checkResponseFormat(response_text) == "XML":
dictionary = xmltodict.parse(response_text)
if "C4ErrorResponse" in dictionary:
if (
"details" in dictionary["C4ErrorResponse"]
and dictionary["C4ErrorResponse"]["details"] in ERROR_DETAILS
):
exception = ERROR_DETAILS.get(dictionary["C4ErrorResponse"]["details"])
raise exception(response_text)
else:
exception = ERROR_CODES.get(
str(dictionary["C4ErrorResponse"]["code"]), C4Exception
)
raise exception(response_text)
elif "code" in dictionary:
if "details" in dictionary and dictionary["details"] in ERROR_DETAILS:
exception = ERROR_DETAILS.get(dictionary["details"])
raise exception(response_text)
else:
exception = ERROR_CODES.get(str(dictionary["code"]), C4Exception)
raise exception(response_text)
elif "error" in dictionary:
if "details" in dictionary and dictionary["details"] in DIRECTOR_ERROR_DETAILS:
exception = DIRECTOR_ERROR_DETAILS.get(dictionary["details"])
raise exception(response_text)
else:
exception = DIRECTOR_ERRORS.get(str(dictionary["error"]), C4Exception)
raise exception(response_text)
Functions
async def checkResponseForError(response_text: str)
-
Checks a string response from the Control4 API for error codes.
Parameters
response_text
- JSON or XML response from Control4, as a string.Expand source code
async def checkResponseForError(response_text: str): """Checks a string response from the Control4 API for error codes. Parameters: `response_text` - JSON or XML response from Control4, as a string. """ if await __checkResponseFormat(response_text) == "JSON": dictionary = json.loads(response_text) elif await __checkResponseFormat(response_text) == "XML": dictionary = xmltodict.parse(response_text) if "C4ErrorResponse" in dictionary: if ( "details" in dictionary["C4ErrorResponse"] and dictionary["C4ErrorResponse"]["details"] in ERROR_DETAILS ): exception = ERROR_DETAILS.get(dictionary["C4ErrorResponse"]["details"]) raise exception(response_text) else: exception = ERROR_CODES.get( str(dictionary["C4ErrorResponse"]["code"]), C4Exception ) raise exception(response_text) elif "code" in dictionary: if "details" in dictionary and dictionary["details"] in ERROR_DETAILS: exception = ERROR_DETAILS.get(dictionary["details"]) raise exception(response_text) else: exception = ERROR_CODES.get(str(dictionary["code"]), C4Exception) raise exception(response_text) elif "error" in dictionary: if "details" in dictionary and dictionary["details"] in DIRECTOR_ERROR_DETAILS: exception = DIRECTOR_ERROR_DETAILS.get(dictionary["details"]) raise exception(response_text) else: exception = DIRECTOR_ERRORS.get(str(dictionary["error"]), C4Exception) raise exception(response_text)
Classes
class BadCredentials (message)
-
Raised when provided credentials are incorrect.
Expand source code
class BadCredentials(Unauthorized): """Raised when provided credentials are incorrect."""
Ancestors
- Unauthorized
- C4Exception
- builtins.Exception
- builtins.BaseException
class BadToken (message)
-
Raised when director bearer token is invalid.
Expand source code
class BadToken(Unauthorized): """Raised when director bearer token is invalid."""
Ancestors
- Unauthorized
- C4Exception
- builtins.Exception
- builtins.BaseException
class C4Exception (message)
-
Base error for pyControl4.
Expand source code
class C4Exception(Exception): """Base error for pyControl4.""" def __init__(self, message): self.message = message
Ancestors
- builtins.Exception
- builtins.BaseException
Subclasses
class InvalidCategory (message)
-
Raised when an invalid category is provided when calling
C4Director.getAllItemsByCategory()
.Expand source code
class InvalidCategory(C4Exception): """Raised when an invalid category is provided when calling `pyControl4.director.C4Director.getAllItemsByCategory`."""
Ancestors
- C4Exception
- builtins.Exception
- builtins.BaseException
class NotFound (message)
-
Raised when a 404 response is recieved from the Control4 API. Occurs when the requested controller, etc. could not be found.
Expand source code
class NotFound(C4Exception): """Raised when a 404 response is recieved from the Control4 API. Occurs when the requested controller, etc. could not be found."""
Ancestors
- C4Exception
- builtins.Exception
- builtins.BaseException
-
Raised when unauthorized, but no other recognized details are provided. Occurs when token is invalid.
Expand source code
class Unauthorized(C4Exception): """Raised when unauthorized, but no other recognized details are provided. Occurs when token is invalid."""
Ancestors
- C4Exception
- builtins.Exception
- builtins.BaseException
Subclasses