diff --git a/src/app_error/context.rs b/src/app_error/context.rs index 38e75fd..160127e 100644 --- a/src/app_error/context.rs +++ b/src/app_error/context.rs @@ -89,9 +89,16 @@ impl Context { /// Attach a metadata [`Field`]. #[must_use] - pub fn with(mut self, field: Field) -> Self { + pub fn with(mut self, mut field: Field) -> Self { + if let Some((_, policy)) = self + .field_policies + .iter() + .rev() + .find(|(name, _)| *name == field.name()) + { + field.set_redaction(*policy); + } self.fields.push(field); - Self::apply_field_redactions(&mut self.fields, &self.field_policies); self } diff --git a/src/app_error/tests.rs b/src/app_error/tests.rs index 6f0b0da..7e74863 100644 --- a/src/app_error/tests.rs +++ b/src/app_error/tests.rs @@ -295,6 +295,21 @@ fn with_details_text_attaches_payload() { assert_eq!(err.details.as_deref(), Some("retry later")); } +#[test] +fn context_with_preserves_default_redaction() { + let err = super::Context::new(AppErrorKind::Service) + .with(field::str("request_id", "abc-123")) + .into_error(DummyError); + + let metadata = err.metadata(); + assert_eq!(metadata.len(), 1); + assert_eq!( + metadata.get("request_id"), + Some(&FieldValue::Str(Cow::Borrowed("abc-123"))) + ); + assert_eq!(metadata.redaction("request_id"), Some(FieldRedaction::None)); +} + #[test] fn context_redact_field_overrides_policy() { let err = super::Context::new(AppErrorKind::Service) @@ -325,6 +340,22 @@ fn context_redact_field_mut_applies_policies() { assert_eq!(metadata.redaction("token"), Some(FieldRedaction::Hash)); } +#[test] +fn context_with_uses_latest_matching_policy() { + let err = super::Context::new(AppErrorKind::Service) + .redact_field("token", FieldRedaction::Hash) + .redact_field("token", FieldRedaction::Redact) + .with(field::str("token", "super-secret")) + .into_error(DummyError); + + let metadata = err.metadata(); + assert_eq!( + metadata.get("token"), + Some(&FieldValue::Str(Cow::Borrowed("super-secret"))) + ); + assert_eq!(metadata.redaction("token"), Some(FieldRedaction::Redact)); +} + #[test] fn app_error_redact_field_updates_metadata() { let err = AppError::internal("boom")