use ic_platform_pocket_ic::ClientError;
#[must_use]
pub fn is_dead_pocket_ic_transport_error(error: &(dyn std::error::Error + 'static)) -> bool {
let mut current = Some(error);
while let Some(candidate) = current {
if let Some(error) = candidate.downcast_ref::<ClientError>() {
return matches!(
error,
ClientError::Transport { .. } | ClientError::Body { .. }
);
}
current = candidate
.downcast_ref::<std::io::Error>()
.and_then(std::io::Error::get_ref)
.map(|inner| inner as &dyn std::error::Error)
.or_else(|| candidate.source());
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn application_messages_cannot_impersonate_typed_transport_failures() {
let message = "HTTP failure: reqwest::Error { kind: Request, url: \"http://127.0.0.1:1234/instances/0/read/get_time\", source: hyper::Error(IncompleteMessage) }";
assert!(!is_dead_pocket_ic_transport_error(&ClientError::Protocol(
message.into()
)));
assert!(!is_dead_pocket_ic_transport_error(&std::io::Error::other(
message
)));
}
}