pub struct ContextChain { /* private fields */ }Expand description
Error chain for tracking causality across system boundaries.
§Purpose
Honeypot systems often need to track error propagation across multiple subsystems while maintaining public/internal separation at each hop.
This type provides:
- Stack-like error accumulation
- Causality timestamps
- Cross-boundary sanitization
§Security
Each link in the chain maintains its own public/internal separation. Exposing the chain to external systems only reveals public contexts.
§Clone Policy
⚠️ This type does NOT implement Clone.
Cloning error chains would:
- Duplicate sensitive internal contexts across memory
- Create multiple zeroization sites with unpredictable drop order
- Violate threat model assumptions about data lifetime
If you need to share chain information:
- Use borrowing (
&ContextChain) for read-only access - Use
external_summary()for public-safe string representation - Use
safe_clone_public()to create a sanitized clone (see method docs)
This is a deliberate design decision to prevent accidental security
violations via casual .clone() calls.
§Example
use palisade_errors::{ContextChain, DualContextError, OperationCategory};
let root = DualContextError::with_lie(
"Operation failed",
"Database connection refused",
OperationCategory::IO,
);
let mut chain = ContextChain::new(root);
let retry_failed = DualContextError::with_lie(
"Retry failed",
"Max retries (3) exceeded",
OperationCategory::System,
);
chain.push(retry_failed);
assert_eq!(chain.depth(), 2);Implementations§
Source§impl ContextChain
impl ContextChain
Sourcepub fn new(root: DualContextError) -> Self
pub fn new(root: DualContextError) -> Self
Create a new chain with a root error.
Sourcepub fn push(&mut self, error: DualContextError)
pub fn push(&mut self, error: DualContextError)
Add a new error to the chain (as the new head).
§Example
let mut chain = ContextChain::new(root);
let next_error = DualContextError::with_lie(
"Propagated error",
"Original error: connection refused",
OperationCategory::System,
);
chain.push(next_error);Sourcepub fn root(&self) -> &DualContextError
pub fn root(&self) -> &DualContextError
Get the root cause error (first in chain).
Sourcepub fn head(&self) -> &DualContextError
pub fn head(&self) -> &DualContextError
Get the final error (last in chain).
Sourcepub fn iter(&self) -> impl Iterator<Item = &DualContextError>
pub fn iter(&self) -> impl Iterator<Item = &DualContextError>
Iterate over the error chain from root to head.
Sourcepub fn external_summary(&self) -> String
pub fn external_summary(&self) -> String
Get external representation of the entire chain (public contexts only).
§Returns
A string showing the public message progression from root to head.
§Use Case
This method exists as the safe alternative to cloning for most scenarios:
- Logging to external systems
- User-facing error messages
- Telemetry and alerting
If you need the chain structure itself without internal contexts, consider whether you actually need the structure or just the narrative flow. In most cases, this string representation is sufficient.
§Performance
Pre-calculates capacity to avoid multiple allocations during formatting.
§Example
let external = chain.external_summary();
// Output: "Database error → Retry failed"