Files
kaptan/firmware/libs/kaptan-err-reportable/tests/propagate.rs
T

150 lines
3.8 KiB
Rust

use kaptan_err_reportable::{ErrorId, KaptanError, ReportableError};
#[derive(Clone, Copy, Debug, Eq, PartialEq, KaptanError)]
enum TestError {
#[kaptan_error(id = 65001)]
Failed,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, KaptanError)]
enum OuterError {
#[kaptan_error(id = 65002)]
Converted(TestError),
}
impl From<TestError> for OuterError {
fn from(error: TestError) -> Self {
Self::Converted(error)
}
}
fn fail() -> Result<(), TestError> {
Err(TestError::Failed)
}
fn middle() -> Result<(), TestError> {
fail()
}
#[kaptan_err_reportable::propagate]
fn succeeds() -> Result<u8, TestError> {
Ok(7)
}
#[kaptan_err_reportable::propagate]
fn annotated_outer() -> Result<(), TestError> {
middle()?;
Ok(())
}
#[kaptan_err_reportable::propagate]
fn annotated_inner() -> Result<(), TestError> {
fail()
}
fn unannotated_outer() -> Result<(), TestError> {
annotated_inner()
}
#[kaptan_err_reportable::propagate]
fn handles_inner_error() -> Result<(), TestError> {
let _handled = fail().is_err();
Ok(())
}
#[kaptan_err_reportable::propagate]
fn returns_explicit_error(report_error: bool) -> Result<(), TestError> {
if report_error {
return Err(TestError::Failed);
}
Ok(())
}
type AliasedResult<T> = core::result::Result<T, TestError>;
#[kaptan_err_reportable::propagate]
fn returns_alias() -> AliasedResult<()> {
fail()
}
#[kaptan_err_reportable::propagate]
fn reports_converted_error() -> Result<(), OuterError> {
fail()?;
Ok(())
}
#[kaptan_err_reportable::propagate]
fn reports_error_id() -> Result<(), ErrorId> {
Err(ErrorId::new(65003))
}
#[kaptan_err_reportable::propagate]
async fn async_reporting_point() -> Result<(), TestError> {
fail()?;
Ok(())
}
struct Service;
impl Service {
#[kaptan_err_reportable::propagate]
fn method(&self, report_error: bool) -> Result<(), TestError> {
if report_error {
fail()?;
}
Ok(())
}
}
fn take_record() -> kaptan_err_reportable::ErrorRecord {
kaptan_err_reportable::take().expect("escaping error must be reported")
}
#[test]
fn reports_only_errors_leaving_annotated_reporting_points() {
while kaptan_err_reportable::take().is_some() {}
assert_eq!(succeeds(), Ok(7));
assert!(kaptan_err_reportable::take().is_none());
assert_eq!(handles_inner_error(), Ok(()));
assert!(kaptan_err_reportable::take().is_none());
assert_eq!(annotated_outer(), Err(TestError::Failed));
assert_eq!(take_record().id(), TestError::Failed.error_id().get());
assert_eq!(unannotated_outer(), Err(TestError::Failed));
assert_eq!(take_record().id(), TestError::Failed.error_id().get());
assert_eq!(returns_explicit_error(true), Err(TestError::Failed));
assert_eq!(take_record().id(), TestError::Failed.error_id().get());
assert_eq!(returns_alias(), Err(TestError::Failed));
assert_eq!(take_record().id(), TestError::Failed.error_id().get());
assert_eq!(
reports_converted_error(),
Err(OuterError::Converted(TestError::Failed))
);
assert_eq!(
take_record().id(),
OuterError::Converted(TestError::Failed).error_id().get()
);
assert_eq!(reports_error_id(), Err(ErrorId::new(65003)));
assert_eq!(take_record().id(), 65003);
assert_eq!(Service.method(false), Ok(()));
assert!(kaptan_err_reportable::take().is_none());
let mut future = core::pin::pin!(async_reporting_point());
let mut context = core::task::Context::from_waker(core::task::Waker::noop());
assert_eq!(
core::future::Future::poll(future.as_mut(), &mut context),
core::task::Poll::Ready(Err(TestError::Failed))
);
let record = take_record();
assert_eq!(record.id(), TestError::Failed.error_id().get());
assert!(record.raised_at().contains("propagate.rs:"));
}