Skip to content

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.

from everysk.core.exceptions import DateError

raise DateError('Invalid date format.')


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:

raise ReadonlyError('This field value cannot be changed.')


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:

from everysk.sdk.entities import Datastore
datastore = Datastore()
datastore.validate_type_data()

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:

  RequiredError: The "data" attribute is required.


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:

from everysk.core.signing import unsign

unsign(b'invalid:data')

When we run the code above we get the following, since we are trying to use an invalid unsigned key.

  SigningError: Error trying to unsign data.