use ntex::http::StatusCode;
use ntex::web::HttpResponse;
use serde_json::json;
pub fn error(status: u16, message: impl Into<String>) -> HttpResponse {
HttpResponse::build(StatusCode::from_u16(status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR))
.json(&json!({ "error": message.into() }))
}
pub fn db_error(e: apiplant_db::Error) -> HttpResponse {
match e {
apiplant_db::Error::BadInput(msg) => error(400, msg),
apiplant_db::Error::Db(ref dberr) => {
let msg = dberr.to_string();
let lower = msg.to_lowercase();
if lower.contains("foreign key") {
if lower.contains("delete on table") || lower.contains("still referenced from") {
error(400, "other records still reference this one")
} else {
error(400, "references a record that does not exist")
}
} else if lower.contains("unique") || lower.contains("duplicate key") {
error(409, "a record with these values already exists")
} else if lower.contains("not-null") || lower.contains("not null") {
error(400, "a required field is missing")
} else {
crate::telemetry::record_error("database", &msg);
tracing::error!(error = %msg, "database error");
error(500, "internal error")
}
}
other => {
crate::telemetry::record_error("database", &other);
tracing::error!(error = %other, "database error");
error(500, "internal error")
}
}
}
pub fn ok(value: &serde_json::Value) -> HttpResponse {
HttpResponse::Ok().json(value)
}