use actix_web::http::StatusCode;
use serde_json::json;
use crate::error::{ErrorCategory, ProcessedError, generate_trace_id};
pub fn process_tokio_postgres_error(
err: &tokio_postgres::Error,
context: Option<&str>,
) -> ProcessedError {
let trace_id = generate_trace_id();
if let Some(db_err) = err.as_db_error() {
let code = db_err.code().code();
let message = db_err.message().to_string();
let (status, error_code, category) = match code {
"23505" => (
StatusCode::CONFLICT,
"unique_violation",
ErrorCategory::DatabaseConstraint,
),
"23503" => (
StatusCode::CONFLICT,
"foreign_key_violation",
ErrorCategory::DatabaseConstraint,
),
"23502" => (
StatusCode::BAD_REQUEST,
"not_null_violation",
ErrorCategory::DatabaseConstraint,
),
_ if code.starts_with("22") => (StatusCode::BAD_REQUEST, "data_exception", ErrorCategory::QuerySyntax),
_ if code.starts_with("42") => (StatusCode::BAD_REQUEST, "query_syntax", ErrorCategory::QuerySyntax),
_ => (StatusCode::INTERNAL_SERVER_ERROR, "db_error", ErrorCategory::Internal),
};
let mut processed = ProcessedError::new(
category,
status,
error_code,
message,
trace_id,
)
.with_metadata("sql_state", json!(code));
if let Some(ctx) = context {
processed = processed.with_metadata("context", json!(ctx));
}
return processed;
}
let mut processed = ProcessedError::new(
ErrorCategory::DatabaseConnection,
StatusCode::BAD_GATEWAY,
"postgres_driver_error",
err.to_string(),
trace_id,
);
if let Some(ctx) = context {
processed = processed.with_metadata("context", json!(ctx));
}
processed
}
pub fn process_tokio_postgres_db_error(
sql_state: &str,
message: &str,
context: Option<&str>,
) -> ProcessedError {
let trace_id = generate_trace_id();
let (status, error_code, category) = match sql_state {
"23505" => (StatusCode::CONFLICT, "unique_violation", ErrorCategory::DatabaseConstraint),
"23503" => (StatusCode::CONFLICT, "foreign_key_violation", ErrorCategory::DatabaseConstraint),
"23502" => (StatusCode::BAD_REQUEST, "not_null_violation", ErrorCategory::DatabaseConstraint),
_ if sql_state.starts_with("22") => (StatusCode::BAD_REQUEST, "data_exception", ErrorCategory::QuerySyntax),
_ if sql_state.starts_with("42") => (StatusCode::BAD_REQUEST, "query_syntax", ErrorCategory::QuerySyntax),
_ => (StatusCode::INTERNAL_SERVER_ERROR, "db_error", ErrorCategory::Internal),
};
let mut processed = ProcessedError::new(
category,
status,
error_code,
message.to_string(),
trace_id,
)
.with_metadata("sql_state", json!(sql_state));
if let Some(ctx) = context {
processed = processed.with_metadata("context", json!(ctx));
}
processed
}