blob: 1587e25bc3aa693648195ba6252c5e27b44093ff [file] [edit]
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! This module defines the Proxy error types.
use std::fmt;
use std::io;
use std::net::SocketAddr;
/// Represents all possible errors that can occur in the http-proxy crate.
#[derive(Debug)]
pub enum Error {
/// An I/O error occurred.
IoError(io::Error),
/// The HTTP request-line is malformed.
MalformedRequestLine(String),
/// The 'Host' header is missing.
MissingHostHeader,
/// The proxy server returned an error.
ConnectionError(SocketAddr, String),
/// The proxy configuration string is malformed.
MalformedConfigString,
/// The port number in the proxy configuration is invalid.
InvalidPortNumber,
/// The host in the proxy configuration is invalid.
InvalidHost,
}
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::IoError(a), Self::IoError(b)) => a.kind() == b.kind(),
(Self::MalformedRequestLine(a), Self::MalformedRequestLine(b)) => a == b,
(Self::MissingHostHeader, Self::MissingHostHeader) => true,
(Self::ConnectionError(a, b), Self::ConnectionError(c, d)) => a == c && b == d,
(Self::MalformedConfigString, Self::MalformedConfigString) => true,
(Self::InvalidPortNumber, Self::InvalidPortNumber) => true,
(Self::InvalidHost, Self::InvalidHost) => true,
_ => false,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::IoError(err) => write!(f, "I/O error: {}", err),
Error::MalformedRequestLine(line) => {
write!(f, "Malformed request line: '{}'", line)
}
Error::MissingHostHeader => write!(f, "Mandatory 'Host' header is missing"),
Error::ConnectionError(addr, msg) => {
write!(f, "Connection to {} failed: {}", addr, msg)
}
Error::MalformedConfigString => write!(f, "Malformed configuration string"),
Error::InvalidPortNumber => write!(f, "Invalid port number"),
Error::InvalidHost => write!(f, "Invalid host"),
}
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Error::IoError(err)
}
}
/// A type alias for `Result` where the error type is this crate's `Error`.
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_io_error_chaining() {
let inner_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let outer_error = Error::IoError(inner_error);
assert!(outer_error.to_string().contains("file not found"));
}
}