Exceptions
This module is a collection of custom exception classes designed to handle errors then raise specific exceptions based on those errors. They also provide attributes and methods to improve the debugging experience.
from typing import Any
from everysk.core.exceptions import EntityError
def validate_entity(entity: Any) -> None:
if not entity:
raise EntityError("Invalid entity")
Starting on the top of the exceptions module, we will be having a _BaseException class which inherits from python's Exception.
flowchart TB
classDef orangeBorder fill:#1A1A1A,color:#E2E2E2,stroke:#FF9933,stroke-width:2px;
pythonException(["Exception"]):::orangeBorder
pythonException --> entitiesDir
entitiesDir(["_BaseException"]):::orangeBorder
entitiesDir --> portfolio["DateError"]:::orangeBorder
entitiesDir --> datastore["EntityError"]:::orangeBorder
entitiesDir --> file["FieldValueError"]:::orangeBorder
entitiesDir --> report["HttpError"]:::orangeBorder
entitiesDir --> customIndex["SDKError"]:::orangeBorder
entitiesDir --> privateSecurity["RequiredError"]:::orangeBorder
The _BaseException class provides an attribute called msg, which will be used when raising errors.
Below, let's take an in-depth look at every exception class inside the exceptions module.
APIError¶
The APIError exception class is used to handle errors that occur when interacting with an API, it could be a Bad Request, Unauthorized, Forbidden, Not Found, etc.
Below we have an implementation example of a theoretical application which raises an APIError when the status code is 400.
from everysk.core.exceptions import APIError
if code == 400:
raise APIError(code=400, message='{"error": "Bad Request"}')
DateError¶
The DateError exception class can be used for handling errors that are related to dates.
Let's take a look at how this would look like in practice with an example of an exception that occurs when we have an invalid date.
DefaultError¶
Some base classes inside Everysk Library can accept default values, but depending on the scenario we might want to filter these values. To achieve this the DefaultError exception can be used.
from everysk.core.exceptions import DefaultError
if isinstance(default, (list, set)):
raise DefaultError('default values cannot be a list or a set.')
EntityError¶
Entities are a fundamental moving part of the Everysk Library, they can be created, saved, retrieved, deleted, and updated. Along the way errors can occur and for that we have the EntityError exception class, which is used for many of those cases.
Take a look at the example below showcasing an error when trying to delete an entity.
from everysk.core.exceptions import EntityError
raise EntityError(f'Error when deleting the entity: {entity.id}.')
EntityNotFound¶
The EntityError mentioned above is used for more general errors as mentioned previously.
The EntityNotFound exception is designed with the sole purpose of raising errors when some entity is not found.
Below we have some code which raises an EntityNotFound exception when trying to update:
from everysk.core.exceptions import EntityNotFound
if entity is None:
raise EntityNotFound(f'Entity not found for update.')
FieldValueError¶
The FieldValueError is mostly used inside the fields module to raise errors related to invalid arguments depending on the context. This exception inherits from Python's ValueError providing the functionality needed.
Below we have an example of an error raised when an integer has a value less than zero:
from everysk.core.exceptions import FieldValueError
if size < 0:
raise FieldValueError('size cannot be a negative number.')
HttpError¶
The HttpError can be implemented for cases when we might have an unsuccessful http request.
Below we have a common example of a response returning an error when the request failed.
from everysk.core.exceptions import HttpError
if response == 'error':
raise HttpError(status_code=500, msg='Internal Server Error')
Since all the exceptions inherit from a _BaseException class we are able to provide a few attributes in the exception for better comprehension of the error.
InvalidArgumentError¶
The InvalidArgumentError exception class can used for specific cases where we have an incorrect argument for some value. Like in the example below when we try to make an API request with an invalid API SID:
from everysk.core.exceptions import InvalidArgumentError
if not api_sid:
raise InvalidArgumentError('Invalid API SID.')
QueryError¶
The QueryError exception class is designed for handling errors that result from invalid queries.
Below we have a code example:
from everysk.core.exceptions import QueryError
if not entity and self.query is None:
raise QueryError(f'No Entity found for this query: {self.query}.')
ReadonlyError¶
Most field classes have the functionality of adding a readonly flag with the purpose of setting a value as read-only, in other words, a value that cannot be modified.
The ReadonlyError is designed with this purpose in mind of raising an exception every time the user tries to alter a readonly value.
from everysk.core.fields import DictField
dict_field = DictField(default={'key': 'value'}, readonly=True)
dict_field.default['key'] = 123
When we run the code above in the terminal we see the following message:
RedisEmptyListError¶
Redis lists are linked lists of string values and they can be used to implement stacks and queues. The RedisEmptyListError can be used, as the name suggests, in the cases when we are performing some type of operation in a list, like a pop, and the list is actually empty.
Below we have the implementation code:
from everysk.core.exceptions import RedisEmptyListError
if value is None:
raise RedisEmptyListError(f'The redis list {self.name} is empty.')
RequiredError¶
The RequiredError exception class is designed to be used in cases when we have a class attribute which is required and we want to raise an error in the scenario where the user does not assign the data to anything.
Below we have an example of how this exception would be raised:
We start by importing and instantiating the Datastore entity, right after we call the validate_type_date() method. The first operation executed by this method is checking whether the data attribute is None.
By running the code above in the terminal we see the following message being displayed:
SDKError¶
The SDKError exception class is designed to raise errors related to the manipulation and creation of entities.
Below we have an example of this exception being raised when we are trying to create an entity that already exists:
from everysk.core.exceptions import SDKError
if entity is not None:
raise SDKError(f'Entity already exists. ID {self.id}.')
SDKInternalError¶
Following the thread of SDK related errors, we have the SDKInternalError exception class which is designed with the purpose of raising an error every time something goes wrong internally, like an unexpected request error.
Below we have some implementation code:
from everysk.core.exceptions import SDKInternalError
raise SDKInternalError('Internal Server Error. Please try again or contact support.')
SDKTypeError¶
The SDKTypeError exception class inherits from Python's TypeError providing all the functionality needed for dealing with errors related incorrect data types, such as passing integers where it should be a string.
Below we have an idea of how that would translate to code:
from everysk.core.exceptions import SDKTypeError
if not isinstance(tags, (str, list)):
raise SDKTypeError('The tags value must be a string or a list.')
SDKValueError¶
Lastly on our family of SDK exceptions, we have the SDKValueError exception class, used to raise errors related to incorrect values in attributes or arguments.
Take a look at the example below:
from everysk.core.exceptions import SDKValueError
if operator != '==':
raise SDKValueError(f'Filter by property name operator must be "==".')
SigningError¶
The SigningError exception class is designed to raise errors related to unsigned operations. Take a look at the example below when we are trying to use an invalid data in bytes to perform the operation:
When we run the code above we get the following, since we are trying to use an invalid unsigned key.