Add descriptions to ASGI flow errors

This commit is contained in:
Giovanni Barillari 2025-06-25 20:49:10 +02:00
parent 961dd98574
commit 384f394bd1
No known key found for this signature in database
3 changed files with 21 additions and 15 deletions

View file

@ -56,7 +56,7 @@ pub(crate) fn ws_message_into_py(py: Python, message: Message) -> PyResult<Bound
}
v => {
log::warn!("Unsupported websocket message received {v:?}");
error_flow!()
error_flow!("Transport misbehaving")
}
}
}

View file

@ -1,12 +1,12 @@
use pyo3::exceptions::PyRuntimeError;
use pyo3::prelude::*;
use std::{error, fmt};
use std::{error, fmt, rc::Rc};
#[derive(Debug)]
pub(crate) struct UnsupportedASGIMessage;
#[derive(Debug)]
pub(crate) struct ASGIFlowError;
pub(crate) struct ASGIFlowError(pub Option<Rc<str>>);
#[derive(Debug)]
pub(crate) struct ASGITransportError;
@ -23,7 +23,10 @@ impl fmt::Display for UnsupportedASGIMessage {
impl fmt::Display for ASGIFlowError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ASGI flow error")
match &self.0 {
Some(msg) => write!(f, "ASGI flow error: {msg}"),
None => write!(f, "ASGI flow error"),
}
}
}
@ -47,7 +50,7 @@ impl std::convert::From<PyErr> for UnsupportedASGIMessage {
impl std::convert::From<PyErr> for ASGIFlowError {
fn from(_pyerr: PyErr) -> ASGIFlowError {
ASGIFlowError
ASGIFlowError(None)
}
}
@ -71,7 +74,10 @@ impl std::convert::From<ASGITransportError> for PyErr {
macro_rules! error_flow {
() => {
Err(super::errors::ASGIFlowError.into())
Err(super::errors::ASGIFlowError(None).into())
};
($msg:expr) => {
Err(super::errors::ASGIFlowError(Some($msg.into())).into())
};
}

View file

@ -183,7 +183,7 @@ impl ASGIHTTPProtocol {
.compare_exchange(false, true, atomic::Ordering::Relaxed, atomic::Ordering::Relaxed)
.is_err()
{
return error_flow!();
return error_flow!("Response already started");
}
// NOTE: we could definitely avoid this check, and always start a streamed response
@ -244,7 +244,7 @@ impl ASGIHTTPProtocol {
}
(true, true, true) => match &*self.body_tx.lock().unwrap() {
Some(tx) => self.send_body(py, tx, body, false),
_ => error_flow!(),
_ => error_flow!("Transport not initialized or closed"),
},
(true, false, true) => match self.body_tx.lock().unwrap().take() {
Some(tx) => match body.is_empty() {
@ -254,9 +254,9 @@ impl ASGIHTTPProtocol {
empty_future_into_py(py)
}
},
_ => error_flow!(),
_ => error_flow!("Transport not initialized or closed"),
},
_ => error_flow!(),
_ => error_flow!("Response not started"),
}
}
Ok(ASGIMessageType::HTTPResponseFile(file_path)) => match (
@ -288,7 +288,7 @@ impl ASGIHTTPProtocol {
});
empty_future_into_py(py)
}
_ => error_flow!(),
_ => error_flow!("Response not started"),
},
Err(err) => Err(err.into()),
_ => error_message!(),
@ -388,7 +388,7 @@ impl ASGIWebsocketProtocol {
}
}
}
FutureResultToPy::Err(error_flow!())
FutureResultToPy::Err(error_flow!("Connection already upgraded"))
})
}
@ -409,7 +409,7 @@ impl ASGIWebsocketProtocol {
}
}
}
FutureResultToPy::Err(error_flow!())
FutureResultToPy::Err(error_flow!("Transport not initialized or closed"))
})
}
@ -492,7 +492,7 @@ impl ASGIWebsocketProtocol {
}
}
}
FutureResultToPy::Err(error_flow!())
FutureResultToPy::Err(error_flow!("Transport not initialized or closed"))
})
}
@ -579,7 +579,7 @@ fn adapt_body(py: Python, message: &Bound<PyDict>) -> (Box<[u8]>, bool) {
fn adapt_file(py: Python, message: &Bound<PyDict>) -> PyResult<String> {
match message.get_item(pyo3::intern!(py, "path"))? {
Some(item) => item.extract(),
_ => error_flow!(),
_ => error_message!(),
}
}