use crate::storage::{
DbErrorGeneric, DbErrorRead, DbErrorReadWithTimeout, DbErrorStubResponse, DbErrorWrite,
DbErrorWriteNonRetriable, SubscribeToResponsesError,
};
use std::{panic::Location, sync::Arc};
use tokio_postgres::error::SqlState;
use tracing_error::SpanTrace;
impl From<tokio_postgres::Error> for DbErrorGeneric {
#[track_caller]
fn from(err: tokio_postgres::Error) -> DbErrorGeneric {
DbErrorGeneric::Uncategorized {
reason: err.to_string().into(),
context: SpanTrace::capture(),
source: Some(Arc::new(err)),
loc: Location::caller(),
}
}
}
impl From<tokio_postgres::Error> for DbErrorRead {
#[track_caller]
fn from(err: tokio_postgres::Error) -> Self {
let err_str = err.to_string();
if err_str == "query returned an unexpected number of rows" {
DbErrorRead::NotFound
} else {
DbErrorRead::from(DbErrorGeneric::from(err))
}
}
}
impl From<tokio_postgres::Error> for DbErrorReadWithTimeout {
#[track_caller]
fn from(err: tokio_postgres::Error) -> Self {
Self::from(DbErrorRead::from(err))
}
}
impl From<tokio_postgres::Error> for SubscribeToResponsesError {
#[track_caller]
fn from(err: tokio_postgres::Error) -> Self {
Self::from(DbErrorRead::from(err))
}
}
impl From<tokio_postgres::Error> for DbErrorWrite {
#[track_caller]
fn from(err: tokio_postgres::Error) -> Self {
if let Some(code) = err.code()
&& *code == SqlState::UNIQUE_VIOLATION
{
return DbErrorWrite::NonRetriable(DbErrorWriteNonRetriable::Conflict);
}
let err_str = err.to_string();
if err_str == "query returned an unexpected number of rows" {
DbErrorWrite::NotFound
} else {
DbErrorWrite::from(DbErrorGeneric::from(err))
}
}
}
impl From<tokio_postgres::Error> for DbErrorStubResponse {
#[track_caller]
fn from(err: tokio_postgres::Error) -> Self {
DbErrorStubResponse::Write(DbErrorWrite::from(err))
}
}
impl From<deadpool_postgres::PoolError> for DbErrorGeneric {
#[track_caller]
fn from(err: deadpool_postgres::PoolError) -> DbErrorGeneric {
match err {
deadpool_postgres::PoolError::Closed => DbErrorGeneric::Close,
err => DbErrorGeneric::from(err),
}
}
}