8 releases (4 breaking)

new 0.4.2 May 9, 2024
0.4.1 Jun 22, 2023
0.4.0 May 15, 2023
0.3.0 Jul 26, 2022
0.0.0 Oct 27, 2020

#643 in Database interfaces

Download history 32/week @ 2024-01-22 63/week @ 2024-01-29 100/week @ 2024-02-05 115/week @ 2024-02-12 161/week @ 2024-02-19 139/week @ 2024-02-26 106/week @ 2024-03-04 102/week @ 2024-03-11 64/week @ 2024-03-18 48/week @ 2024-03-25 147/week @ 2024-04-01 84/week @ 2024-04-08 61/week @ 2024-04-15 70/week @ 2024-04-22 119/week @ 2024-04-29 217/week @ 2024-05-06

473 downloads per month
Used in 8 crates (5 directly)

MIT/Apache

32KB
688 lines

EdgeDB Rust Binding: Errors Crate

This crate contains definitions of errors returned from the database.

License

Licensed under either of

at your option.


lib.rs:

Error Handling for EdgeDB

All errors that EdgeDB Rust bindings produce are encapsulated into the Error structure. The structure is a bit like Box<dyn Error> or anyhow::Error, except it can only contain EdgeDB error types. Or UserError can be used to encapsulate custom errors (commonly used to return an error from a transaction).

A full list of EdgeDB error types on a single page can be found on the website documentation.

Each error kind is represented as a separate type that implements the ErrorKind trait. But error kinds are used like marker structs; you can use Error::is for error kinds and use them to create instances of the error:

let err = UserError::with_source(io::Error::from(io::ErrorKind::NotFound));
assert!(err.is::<UserError>());

Since errors are hirarchical, Error::is works with any ancestor:

assert!(err.is::<MissingArgumentError>());
assert!(err.is::<QueryArgumentError>());  // implied by the assertion above
assert!(err.is::<InterfaceError>());  // and this one
assert!(err.is::<ClientError>());  // and this one

Error hierarchy doesn't have multiple inheritance (i.e. every error has only single parent). When we match across different parents we use error tags:


assert!(err1.is::<ClientConnectionTimeoutError>());
assert!(err2.is::<TransactionConflictError>());
// Both of these are retried
assert!(err1.has_tag(SHOULD_RETRY));
assert!(err2.has_tag(SHOULD_RETRY));

// But they aren't a part of common hierarchy
assert!(err1.is::<ClientError>());
assert!(!err1.is::<ExecutionError>());
assert!(err2.is::<ExecutionError>());
assert!(!err2.is::<ClientError>());

Errors in Transactions

Special care for errors must be taken in transactions. Generally:

  1. Errors from queries should not be ignored, and should be propagagated up to the transaction function.
  2. User errors can be encapsulated into UserError via one of the methods:
  1. Original query error must be propagated via error chain. It can be in the .source() chain but must not be swallowed, otherwise retrying transaction may work incorrectly.

Nice Error Reporting

Refer to documentation in the edgedb-tokio crate.

Dependencies

~130–375KB