/* This file is part of gnix (https://codeberg.org/metamuffin/gnix) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin */ #[derive(Debug, thiserror::Error)] pub enum ServiceError { #[error("no response generated; the proxy is misconfigured")] NoResponse, #[error("request taken; the proxy is misconfigured")] RequestTaken, #[error("limit reached. try again")] Limit(#[from] tokio::sync::TryAcquireError), #[error("hyper error: {0}")] Hyper(hyper::Error), #[error("h3 error: {0}")] H3(h3::Error), #[error("host header missing")] NoHost, #[error("unknown host")] UnknownHost, #[error("unknown path")] UnknownPath, #[error("can't connect to the backend")] CantConnect, #[error("not found")] NotFound, #[error("io error: {0}")] Io(#[from] std::io::Error), #[error("bad range")] BadRange, #[error("bad utf8")] BadUtf8(#[from] std::str::Utf8Error), #[error("bad utf8")] BadUtf82(#[from] std::string::FromUtf8Error), #[error("bad utf8")] BadUtf83(#[from] http::header::ToStrError), #[error("bad path")] BadPath, #[error("bad auth")] BadAuth, #[error("unauthorized")] Unauthorized, #[error("bad base64: {0}")] BadBase64(#[from] base64::DecodeError), #[error("connection upgrade failed")] UpgradeFailed, #[error("{0}")] Custom(String), #[error("{0}")] CustomStatic(&'static str), #[error("parse int error: {0}")] ParseIntError(#[from] std::num::ParseIntError), #[error("invalid header")] InvalidHeader, #[error("X-Real-IP header missing, your proxy is misconfigured")] XRealIPMissing, #[error("invalid uri")] InvalidUri, #[error("too many concurrent users, please retry later")] TooManyIdentities, #[error("impossible error")] Other, } impl ServiceError { pub fn status_code(&self) -> http::StatusCode { use http::StatusCode; match self { ServiceError::NoResponse => todo!(), ServiceError::RequestTaken => StatusCode::INTERNAL_SERVER_ERROR, ServiceError::Limit(_) => StatusCode::TOO_MANY_REQUESTS, ServiceError::Hyper(_) => StatusCode::INTERNAL_SERVER_ERROR, ServiceError::H3(_) => StatusCode::INTERNAL_SERVER_ERROR, ServiceError::NoHost => StatusCode::BAD_REQUEST, ServiceError::UnknownHost => StatusCode::NOT_FOUND, ServiceError::UnknownPath => StatusCode::NOT_FOUND, ServiceError::CantConnect => StatusCode::BAD_GATEWAY, ServiceError::NotFound => StatusCode::NOT_FOUND, ServiceError::Io(_) => StatusCode::BAD_REQUEST, ServiceError::BadRange => StatusCode::RANGE_NOT_SATISFIABLE, ServiceError::BadUtf8(_) => StatusCode::BAD_REQUEST, ServiceError::BadUtf82(_) => StatusCode::BAD_REQUEST, ServiceError::BadUtf83(_) => StatusCode::BAD_REQUEST, ServiceError::BadPath => StatusCode::BAD_REQUEST, ServiceError::BadAuth => StatusCode::UNAUTHORIZED, ServiceError::Unauthorized => StatusCode::UNAUTHORIZED, ServiceError::BadBase64(_) => StatusCode::BAD_REQUEST, ServiceError::UpgradeFailed => StatusCode::UPGRADE_REQUIRED, ServiceError::Custom(_) => StatusCode::BAD_REQUEST, ServiceError::CustomStatic(_) => StatusCode::BAD_REQUEST, ServiceError::ParseIntError(_) => StatusCode::BAD_REQUEST, ServiceError::InvalidHeader => StatusCode::BAD_REQUEST, ServiceError::XRealIPMissing => StatusCode::INTERNAL_SERVER_ERROR, ServiceError::InvalidUri => StatusCode::BAD_REQUEST, ServiceError::TooManyIdentities => StatusCode::TOO_MANY_REQUESTS, ServiceError::Other => StatusCode::INTERNAL_SERVER_ERROR, } } }