In case of erroneous transactions, connection problems and a lot of other cases, PyLinkAhead may raise specific errors in order to pinpoint the problem as precisely as possible. Some of these errors a representations of errors in the LinkAhead server, others stem from problems that occurred on the client side.
The errors and exceptions are ordered hierarchically form the most general exceptions to specific transaction or connection problems. The most important error types and the hierarchy will be explained in the following. For more information on specific error types, see also the source code.
Starting from PyCaosDB 0.5, the error handling has changed
significantly. New error classes have been introduced and the
EntityError has been
re-worked. In the following, only the “new” errors are
discussed. Please refer to the documentation of PyCaosDB 0.4.1 and
earlier for the old error handling.
Every transaction (calling
delete on a container or an entity) may finish with errors. They
indicate, for instance, that an entity does not exist or that you need
to specify a data type for your property and much more. If and only if
one or more errors occur during a transaction a
will be raised by the transaction method. The
class is a container for all errors which occur during a
transaction. It usually contains one or more entity
errors which you can inspect in order to learn why the
transaction failed. For this inspection, there are some helpful
attributes and methods provided by the
entities: a list of all entities that directly caused at least one error in this transaction.
errors: a list of all
EntityErrorobjects that directly caused the transaction to fail.
all_errors: sets of all entities and errors that, directly or indirectly, caused either this
TransactionErroror any of the
EntityErrorobjects it contains.
has_error(error_t): Check whether an error of type
error_toccurred during the transaction.
print(transaction_error) prints a tree-like
representation of all errors regarding the transaction in question.
EntityError specifies the entity and the error proper that
caused a transaction to fail. It is never raised on its own but is
contained in a
TransactionError (which may or may not contain
EntityError objects) which is then raised.
has several subclasses that further specify the
error that occurred.
EntityError class is in fact a subclass of
TransactionError. Thus, it has the same methods and attributes as
above. This is important in case of an
EntityError that was caused by other faulty entities (e.g., broken
parents or properties). In that case these problematic entities and
errors can again be inspected by visiting the
errors lists as above.
EntityError for special purposes:
BadQueryError is raised when a query could not be processed by
the server. In contrast to a
TransactionError it is not
necessarily caused by problematic entities or
BadQueryError has the two important subclasses
QueryNotUniqueError for queries with
unique=True which found no or ambiguous entities, respectively.
HTTPClientError or an
HTTPServerError is raised in case of
http(s) connection problems caused by the Python client or the LinkAhead
server, respectively. There are the following subclasses of
HTTPClientError that are used to specify the connection problem:
HTTPURITooLongError: The URI of the request was too long to be processed by the server.
HTTPForbiddenError: You’re not allowed to access this resource.
HTTPResourceNotFoundError: The requested resource doesn’t exist.
There are further subclasses of
LinkAheadException that are raised in
case of faulty configurations or other problems. They should be rather
self-explanatory from their names; see the source code
for further information.
import linkahead as db def link_and_insert(entity, linked, link=True): """Link the ENTITY to LINKED and insert it.""" if link: entity.add_property(db.Property(name="link", value=linked)) try: entity.insert() except db.TransactionError as tre: # Unique names problem may be worked around by using another name if tre.has_error(db.UniqueNamesError): for ent_error in tre.errors: if (isinstance(ent_error, db.UniqueNamesError) and entity in ent_error.entities): entity.name = entity.name + "_new" # Try again with new name. link_and_insert(entity, linked, link=False) break # Unqualified properties will be handled by the caller elif tre.has_error(db.UnqualifiedPropertiesError): for ent_error in tre.errors: if (isinstance(ent_error, db.UnqualifiedPropertiesError_ and entity in ent_error.entities): raise RuntimeError("One of the properties was unqualified: " + str(ent_error)) # Other problems are not covered by this tutorial else: raise NotImplementedError("Unhandled TransactionError: " + str(tre))