// Copyright (C) 2023-2099 The crate authors. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published by the // Free Software Foundation, either version 3 of the License, or (at your // option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License // for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . use std::env::VarError; use std::error::Error as StdError; use std::io::Error as IoError; use std::str::Utf8Error; use hex::FromHexError; use hmac::digest::InvalidLength as HmacInvalidLength; use hyper::StatusCode; #[derive(Debug)] pub enum Error { MethodMismatch(hyper::Method), InvalidSecret, InvalidContentType, InvalidSignature, InvalidRequest, UnsupportedHookConversion, Hex(FromHexError), Hmac(HmacInvalidLength), Hyper(hyper::Error), Io(IoError), SerdeJson(serde_json::Error), Toml(toml::de::Error), Utf8(Utf8Error), Var(VarError), } impl Error { pub fn status(&self) -> StatusCode { match self { Self::MethodMismatch(_) => StatusCode::METHOD_NOT_ALLOWED, Self::InvalidSecret => StatusCode::FORBIDDEN, Self::InvalidContentType => StatusCode::UNSUPPORTED_MEDIA_TYPE, Self::InvalidSignature => StatusCode::FORBIDDEN, Self::InvalidRequest => StatusCode::BAD_REQUEST, _ => StatusCode::INTERNAL_SERVER_ERROR, } } } impl StdError for Error {} impl std::fmt::Display for Error { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Error::MethodMismatch(method) => { write!(fmt, "method is invalid {method}, expected POST") } Error::InvalidSecret => write!(fmt, "the secret is invalid"), Error::InvalidContentType => write!(fmt, "the content-type is invalid"), Error::InvalidSignature => write!(fmt, "the signature is invalid"), Error::InvalidRequest => write!(fmt, "the request is invalid"), Error::UnsupportedHookConversion => write!(fmt, "Unable to convert hook"), Error::Hex(e) => write!(fmt, "hex error: {}", e), Error::Hmac(e) => write!(fmt, "hmac error: {}", e), Error::Hyper(e) => write!(fmt, "hyper error: {}", e), Error::Io(e) => write!(fmt, "Io error: {}", e), Error::SerdeJson(e) => write!(fmt, "serde_json error: {}", e), Error::Toml(e) => write!(fmt, "toml deserialization error: {}", e), Error::Utf8(e) => write!(fmt, "Utf8 error: {}", e), Error::Var(e) => write!(fmt, "Var error: {}", e), } } } impl From for Error { fn from(err: FromHexError) -> Error { Error::Hex(err) } } impl From for Error { fn from(err: HmacInvalidLength) -> Error { Error::Hmac(err) } } impl From for Error { fn from(err: hyper::Error) -> Error { Error::Hyper(err) } } impl From for Error { fn from(err: IoError) -> Error { Error::Io(err) } } impl From for Error { fn from(err: serde_json::Error) -> Error { Error::SerdeJson(err) } } impl From for Error { fn from(err: toml::de::Error) -> Error { Error::Toml(err) } } impl From for Error { fn from(err: Utf8Error) -> Error { Error::Utf8(err) } } impl From for Error { fn from(err: VarError) -> Error { Error::Var(err) } }