sqlx_error/lib.rs
1//! # sqlx-error
2//!
3//! A wrapper around `sqlx::Error` to provide error path and additional context.
4//!
5//! ## Usage
6//!
7//! ```rust
8//! use sqlx_error::{sqlx_error, SqlxError};
9//!
10//! #[derive(Debug, thiserror::Error)]
11//! pub enum MyError {
12//! #[error(transparent)]
13//! Sqlx(#[from] SqlxError),
14//! }
15//!
16//! /// If you have a single sqlx query per function, the function path by itself could provide
17//! /// enough context
18//! fn foo() -> Result<(), MyError> {
19//! Err(sqlx::Error::RowNotFound).map_err(sqlx_error!())?;
20//! Ok(())
21//! }
22//!
23//! /// Or you can add more context
24//! fn bar() -> Result<(), MyError> {
25//! Err(sqlx::Error::RowNotFound).map_err(sqlx_error!("more context"))?;
26//! Ok(())
27//! }
28//!
29//! # fn main() {
30//! assert_eq!(foo().unwrap_err().to_string(), "sqlx rust_out::foo, src/lib.rs:15:43");
31//! assert_eq!(bar().unwrap_err().to_string(), "sqlx rust_out::bar, src/lib.rs:21:43, more context");
32//! # }
33//! ```
34
35#![warn(clippy::all, missing_docs, nonstandard_style, future_incompatible)]
36
37use ::std::{error::Error, fmt, option::Option};
38
39/// Sqlx error wrapper to hold additional info
40#[derive(Debug)]
41pub struct SqlxError(::sqlx_core::error::Error, String);
42
43/// A `Result` based on `SqlxError`
44pub type SqlxResult<T> = Result<T, SqlxError>;
45
46/// The macro adds error path and optional description to`sqlx::Error`.
47///
48/// If you have a single sqlx query per function and the function path by itself provides enough
49/// context you can just use `sqlx_error!()`. If it's not enough you can provide an additional
50/// message with `sqlx_error!("more context")`.
51#[macro_export]
52macro_rules! sqlx_error {
53 () => {
54 |e| $crate::SqlxError::new(e, code_path::code_path!().into())
55 };
56 ($desc:expr) => {
57 |e| $crate::SqlxError::new(e, format!("{}, {}", code_path::code_path!(), $desc))
58 };
59}
60
61impl SqlxError {
62 /// Creates an `SqlxError` instance
63 pub fn new(err: sqlx_core::error::Error, msg: String) -> Self {
64 Self(err, msg)
65 }
66}
67
68impl fmt::Display for SqlxError {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 write!(f, "sqlx {}", self.1)
71 }
72}
73
74impl Error for SqlxError {
75 fn source(&self) -> Option<&(dyn Error + 'static)> {
76 Option::Some(&self.0)
77 }
78}