use std::error::Error;
use crate::{frame::FrameProtocolError, quic::ConnectionErrorIncoming};
use super::codes::Code;
use std::fmt::Display;
#[derive(Debug, Clone, Hash)]
pub struct InternalConnectionError {
pub(crate) code: Code,
pub(crate) message: String,
}
impl InternalConnectionError {
pub fn new(code: Code, message: String) -> Self {
Self { code, message }
}
pub fn got_frame_error(value: FrameProtocolError) -> Self {
match value {
FrameProtocolError::InvalidStreamId(id) => InternalConnectionError {
code: Code::H3_ID_ERROR,
message: format!("invalid stream id: {}", id),
},
FrameProtocolError::InvalidPushId(id) => InternalConnectionError {
code: Code::H3_ID_ERROR,
message: format!("invalid push id: {}", id),
},
FrameProtocolError::Settings(error) => InternalConnectionError {
code: Code::H3_SETTINGS_ERROR,
message: error.to_string(),
},
FrameProtocolError::ForbiddenFrame(number) => InternalConnectionError {
code: Code::H3_FRAME_UNEXPECTED,
message: format!("received a forbidden frame with number {}", number),
},
FrameProtocolError::InvalidFrameValue | FrameProtocolError::Malformed => InternalConnectionError {
code: Code::H3_FRAME_ERROR,
message: "frame payload that contains additional bytes after the identified fields or a frame payload that terminates before the end of the identified fields".to_string(),
},
}
}
}
#[derive(Debug, Clone)]
pub enum ErrorOrigin {
Internal(InternalConnectionError),
Quic(ConnectionErrorIncoming),
}
impl Display for ErrorOrigin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ErrorOrigin::Internal(error) => write!(f, "Internal Error: {}", error.message),
ErrorOrigin::Quic(error) => write!(f, "Quic Error: {:?}", error),
}
}
}
impl Error for ErrorOrigin {}
impl From<InternalConnectionError> for ErrorOrigin {
fn from(error: InternalConnectionError) -> Self {
ErrorOrigin::Internal(error)
}
}
impl From<ConnectionErrorIncoming> for ErrorOrigin {
fn from(error: ConnectionErrorIncoming) -> Self {
ErrorOrigin::Quic(error)
}
}