pub struct FrameworkRequestFailure<E, D = BoundedDiagnostic> { /* private fields */ }Expand description
Only the actual context-bound source submission above constructs this value.
No Clone, Default, From
ⓘ
use saddle_observability::FrameworkRequestFailure;
fn naked() -> Result<(), FrameworkRequestFailure<u32>> { Err(17) }ⓘ
use saddle_observability::FrameworkRequestFailure;
fn bypass() -> Result<(), FrameworkRequestFailure<u32>> {
let value: Result<(), u32> = Err(17);
value?;
Ok(())
}ⓘ
use saddle_observability::FrameworkRequestFailure;
fn forged(source: FrameworkRequestFailure<u32>) -> FrameworkRequestFailure<u32> {
FrameworkRequestFailure { error: 17, ..source }
}Implementations§
Source§impl<E, D> FrameworkRequestFailure<E, D>
impl<E, D> FrameworkRequestFailure<E, D>
Sourcepub fn error(&self) -> &E
pub fn error(&self) -> &E
Examples found in repository?
examples/early_request_diagnostic.rs (line 50)
32fn main() {
33 // Caller is at the accepted socket phase; no trace, span, request or task is
34 // fabricated to satisfy a constructor. The output may genuinely be absent.
35 let scope =
36 RequestDiagnosticScope::early(None, EarlyRequestContext::socket_accepted("example"))
37 .with_phase(DiagnosticRequestPhase::ReadingHead);
38 let failure = match read_head(&mut io::empty(), &scope) {
39 Err(failure) => failure,
40 Ok(()) => panic!("owned empty reader must fail"),
41 };
42 let id = failure.source_diagnostic().id();
43 let (retained, delivery) = failure.finish_boundary_retained(
44 None,
45 &DiagnosticOutcomeAxes {
46 operation: OperationOutcome::Failed,
47 ..Default::default()
48 },
49 );
50 assert_eq!(retained.error().kind(), io::ErrorKind::UnexpectedEof);
51 assert_eq!(retained.source_diagnostic().id(), id);
52 assert_eq!(
53 delivery.source_submission(),
54 DiagnosticSubmission::OutputUnavailable
55 );
56 assert_eq!(
57 delivery.boundary_submission(),
58 DiagnosticSubmission::OutputUnavailable
59 );
60 // Real consumer keeps `retained` in its task/response result, not just bool.
61 println!("GO: early source retained without invented identities or output");
62}More examples
examples/outbound_child_diagnostic.rs (line 72)
12fn main() {
13 let observer = Observer::with_writer(ObserverConfig::default(), std::io::sink()).unwrap();
14 let (incoming, _) = observer
15 .start_external_call_with_rpc(
16 "shop",
17 "ingress",
18 "orders",
19 "query",
20 Some("gateway-opaque"),
21 RpcCorrelationId::new("0.3").unwrap(),
22 )
23 .unwrap();
24 let ingress_event = EventContext::new(
25 RequestIdentity::new("request-7").unwrap(),
26 RouteIdentity::new("/incoming").unwrap(),
27 1,
28 )
29 .unwrap();
30 let parent = RequestDiagnosticScope::output_unavailable(incoming.context(), &ingress_event)
31 .with_task(DiagnosticTaskId::from_runtime_id("42").unwrap())
32 .unwrap_or_else(|_| panic!("task"))
33 .with_zone(DiagnosticZone::from_validated_ingress("zone-a").unwrap());
34
35 // programming.rs generates the wire child; Boundary uses its trace/rpc plus
36 // request_id/function. The adapter below does NOT generate these identities.
37 let wire_trace = "gateway-opaque";
38 let wire_rpc = "0.3.1";
39 let request_id = "request-7";
40 let function = "remote.query";
41 let (root, _) = observer
42 .start_external_call_with_rpc(
43 "saddle",
44 "zone-a",
45 "profusecontract",
46 "invoke",
47 Some(wire_trace),
48 RpcCorrelationId::new(wire_rpc).unwrap(),
49 )
50 .unwrap();
51 let event = EventContext::new(
52 RequestIdentity::new(request_id).unwrap(),
53 RouteIdentity::new(function).unwrap(),
54 1,
55 )
56 .unwrap();
57 let child = parent
58 .derive_outbound_child(root.context(), &event)
59 .unwrap();
60 let failure = child.fail(
61 std::io::ErrorKind::ConnectionRefused,
62 DiagnosticCategory::UnexpectedError,
63 BoundedDiagnosticCause::new(
64 DiagnosticStage::RequestDecode,
65 DiagnosticCode::new("outbound.connect_failed").unwrap(),
66 ),
67 );
68 let id = failure.source_diagnostic().id();
69 let (retained, delivery) =
70 failure.finish_boundary_retained(None, &DiagnosticOutcomeAxes::default());
71 assert_eq!(retained.source_diagnostic().id(), id);
72 assert_eq!(*retained.error(), std::io::ErrorKind::ConnectionRefused);
73 assert_eq!(
74 delivery.source_submission(),
75 DiagnosticSubmission::OutputUnavailable
76 );
77 assert_eq!(
78 delivery.boundary_submission(),
79 DiagnosticSubmission::OutputUnavailable
80 );
81 println!("GO: Boundary-shaped child Call/Event consumed; absent output retains same failure");
82}pub fn submission(&self) -> DiagnosticSubmission
pub fn map_error<F>( self, map: impl FnOnce(E) -> F, ) -> FrameworkRequestFailure<F, D>
pub fn record_boundary( &self, output: &EmergencyDiagnosticHandle, axes: &DiagnosticOutcomeAxes, ) -> DiagnosticSubmission
pub fn record_boundary_optional( &self, output: Option<&EmergencyDiagnosticHandle>, axes: &DiagnosticOutcomeAxes, ) -> DiagnosticSubmission
Sourcepub fn finish_boundary_retained(
self,
output: Option<&EmergencyDiagnosticHandle>,
axes: &DiagnosticOutcomeAxes,
) -> (Self, BoundaryDiagnosticDelivery)
pub fn finish_boundary_retained( self, output: Option<&EmergencyDiagnosticHandle>, axes: &DiagnosticOutcomeAxes, ) -> (Self, BoundaryDiagnosticDelivery)
Declared terminal observation without discarding the original error or diagnostic on missing/full/closed output. The returned SAME mandatory carrier must remain in the enclosing result until its actual terminal. This does not prove that arbitrary Rust drop/forget can be forbidden.
Examples found in repository?
examples/early_request_diagnostic.rs (lines 43-49)
32fn main() {
33 // Caller is at the accepted socket phase; no trace, span, request or task is
34 // fabricated to satisfy a constructor. The output may genuinely be absent.
35 let scope =
36 RequestDiagnosticScope::early(None, EarlyRequestContext::socket_accepted("example"))
37 .with_phase(DiagnosticRequestPhase::ReadingHead);
38 let failure = match read_head(&mut io::empty(), &scope) {
39 Err(failure) => failure,
40 Ok(()) => panic!("owned empty reader must fail"),
41 };
42 let id = failure.source_diagnostic().id();
43 let (retained, delivery) = failure.finish_boundary_retained(
44 None,
45 &DiagnosticOutcomeAxes {
46 operation: OperationOutcome::Failed,
47 ..Default::default()
48 },
49 );
50 assert_eq!(retained.error().kind(), io::ErrorKind::UnexpectedEof);
51 assert_eq!(retained.source_diagnostic().id(), id);
52 assert_eq!(
53 delivery.source_submission(),
54 DiagnosticSubmission::OutputUnavailable
55 );
56 assert_eq!(
57 delivery.boundary_submission(),
58 DiagnosticSubmission::OutputUnavailable
59 );
60 // Real consumer keeps `retained` in its task/response result, not just bool.
61 println!("GO: early source retained without invented identities or output");
62}More examples
examples/outbound_child_diagnostic.rs (line 70)
12fn main() {
13 let observer = Observer::with_writer(ObserverConfig::default(), std::io::sink()).unwrap();
14 let (incoming, _) = observer
15 .start_external_call_with_rpc(
16 "shop",
17 "ingress",
18 "orders",
19 "query",
20 Some("gateway-opaque"),
21 RpcCorrelationId::new("0.3").unwrap(),
22 )
23 .unwrap();
24 let ingress_event = EventContext::new(
25 RequestIdentity::new("request-7").unwrap(),
26 RouteIdentity::new("/incoming").unwrap(),
27 1,
28 )
29 .unwrap();
30 let parent = RequestDiagnosticScope::output_unavailable(incoming.context(), &ingress_event)
31 .with_task(DiagnosticTaskId::from_runtime_id("42").unwrap())
32 .unwrap_or_else(|_| panic!("task"))
33 .with_zone(DiagnosticZone::from_validated_ingress("zone-a").unwrap());
34
35 // programming.rs generates the wire child; Boundary uses its trace/rpc plus
36 // request_id/function. The adapter below does NOT generate these identities.
37 let wire_trace = "gateway-opaque";
38 let wire_rpc = "0.3.1";
39 let request_id = "request-7";
40 let function = "remote.query";
41 let (root, _) = observer
42 .start_external_call_with_rpc(
43 "saddle",
44 "zone-a",
45 "profusecontract",
46 "invoke",
47 Some(wire_trace),
48 RpcCorrelationId::new(wire_rpc).unwrap(),
49 )
50 .unwrap();
51 let event = EventContext::new(
52 RequestIdentity::new(request_id).unwrap(),
53 RouteIdentity::new(function).unwrap(),
54 1,
55 )
56 .unwrap();
57 let child = parent
58 .derive_outbound_child(root.context(), &event)
59 .unwrap();
60 let failure = child.fail(
61 std::io::ErrorKind::ConnectionRefused,
62 DiagnosticCategory::UnexpectedError,
63 BoundedDiagnosticCause::new(
64 DiagnosticStage::RequestDecode,
65 DiagnosticCode::new("outbound.connect_failed").unwrap(),
66 ),
67 );
68 let id = failure.source_diagnostic().id();
69 let (retained, delivery) =
70 failure.finish_boundary_retained(None, &DiagnosticOutcomeAxes::default());
71 assert_eq!(retained.source_diagnostic().id(), id);
72 assert_eq!(*retained.error(), std::io::ErrorKind::ConnectionRefused);
73 assert_eq!(
74 delivery.source_submission(),
75 DiagnosticSubmission::OutputUnavailable
76 );
77 assert_eq!(
78 delivery.boundary_submission(),
79 DiagnosticSubmission::OutputUnavailable
80 );
81 println!("GO: Boundary-shaped child Call/Event consumed; absent output retains same failure");
82}Sourcepub fn source_diagnostic(&self) -> &D
pub fn source_diagnostic(&self) -> &D
Examples found in repository?
examples/early_request_diagnostic.rs (line 42)
32fn main() {
33 // Caller is at the accepted socket phase; no trace, span, request or task is
34 // fabricated to satisfy a constructor. The output may genuinely be absent.
35 let scope =
36 RequestDiagnosticScope::early(None, EarlyRequestContext::socket_accepted("example"))
37 .with_phase(DiagnosticRequestPhase::ReadingHead);
38 let failure = match read_head(&mut io::empty(), &scope) {
39 Err(failure) => failure,
40 Ok(()) => panic!("owned empty reader must fail"),
41 };
42 let id = failure.source_diagnostic().id();
43 let (retained, delivery) = failure.finish_boundary_retained(
44 None,
45 &DiagnosticOutcomeAxes {
46 operation: OperationOutcome::Failed,
47 ..Default::default()
48 },
49 );
50 assert_eq!(retained.error().kind(), io::ErrorKind::UnexpectedEof);
51 assert_eq!(retained.source_diagnostic().id(), id);
52 assert_eq!(
53 delivery.source_submission(),
54 DiagnosticSubmission::OutputUnavailable
55 );
56 assert_eq!(
57 delivery.boundary_submission(),
58 DiagnosticSubmission::OutputUnavailable
59 );
60 // Real consumer keeps `retained` in its task/response result, not just bool.
61 println!("GO: early source retained without invented identities or output");
62}More examples
examples/outbound_child_diagnostic.rs (line 68)
12fn main() {
13 let observer = Observer::with_writer(ObserverConfig::default(), std::io::sink()).unwrap();
14 let (incoming, _) = observer
15 .start_external_call_with_rpc(
16 "shop",
17 "ingress",
18 "orders",
19 "query",
20 Some("gateway-opaque"),
21 RpcCorrelationId::new("0.3").unwrap(),
22 )
23 .unwrap();
24 let ingress_event = EventContext::new(
25 RequestIdentity::new("request-7").unwrap(),
26 RouteIdentity::new("/incoming").unwrap(),
27 1,
28 )
29 .unwrap();
30 let parent = RequestDiagnosticScope::output_unavailable(incoming.context(), &ingress_event)
31 .with_task(DiagnosticTaskId::from_runtime_id("42").unwrap())
32 .unwrap_or_else(|_| panic!("task"))
33 .with_zone(DiagnosticZone::from_validated_ingress("zone-a").unwrap());
34
35 // programming.rs generates the wire child; Boundary uses its trace/rpc plus
36 // request_id/function. The adapter below does NOT generate these identities.
37 let wire_trace = "gateway-opaque";
38 let wire_rpc = "0.3.1";
39 let request_id = "request-7";
40 let function = "remote.query";
41 let (root, _) = observer
42 .start_external_call_with_rpc(
43 "saddle",
44 "zone-a",
45 "profusecontract",
46 "invoke",
47 Some(wire_trace),
48 RpcCorrelationId::new(wire_rpc).unwrap(),
49 )
50 .unwrap();
51 let event = EventContext::new(
52 RequestIdentity::new(request_id).unwrap(),
53 RouteIdentity::new(function).unwrap(),
54 1,
55 )
56 .unwrap();
57 let child = parent
58 .derive_outbound_child(root.context(), &event)
59 .unwrap();
60 let failure = child.fail(
61 std::io::ErrorKind::ConnectionRefused,
62 DiagnosticCategory::UnexpectedError,
63 BoundedDiagnosticCause::new(
64 DiagnosticStage::RequestDecode,
65 DiagnosticCode::new("outbound.connect_failed").unwrap(),
66 ),
67 );
68 let id = failure.source_diagnostic().id();
69 let (retained, delivery) =
70 failure.finish_boundary_retained(None, &DiagnosticOutcomeAxes::default());
71 assert_eq!(retained.source_diagnostic().id(), id);
72 assert_eq!(*retained.error(), std::io::ErrorKind::ConnectionRefused);
73 assert_eq!(
74 delivery.source_submission(),
75 DiagnosticSubmission::OutputUnavailable
76 );
77 assert_eq!(
78 delivery.boundary_submission(),
79 DiagnosticSubmission::OutputUnavailable
80 );
81 println!("GO: Boundary-shaped child Call/Event consumed; absent output retains same failure");
82}Sourcepub fn finish_boundary(
self,
output: &EmergencyDiagnosticHandle,
axes: &DiagnosticOutcomeAxes,
) -> (E, BoundaryDiagnosticDelivery)
pub fn finish_boundary( self, output: &EmergencyDiagnosticHandle, axes: &DiagnosticOutcomeAxes, ) -> (E, BoundaryDiagnosticDelivery)
Sole consuming release of the original error: records its boundary first. The enclosing component must use this only at its declared public boundary, not as an adapter back to a legacy internal technical-failure path.
Source§impl<D> FrameworkRequestFailure<(), D>
impl<D> FrameworkRequestFailure<(), D>
Sourcepub fn into_reference(self) -> RequestBoundaryReference<D>
pub fn into_reference(self) -> RequestBoundaryReference<D>
Consume a capture receipt into its context-preserving boundary reference.
Auto Trait Implementations§
impl<E, D> Freeze for FrameworkRequestFailure<E, D>
impl<E, D> RefUnwindSafe for FrameworkRequestFailure<E, D>where
E: RefUnwindSafe,
D: RefUnwindSafe,
impl<E, D> Send for FrameworkRequestFailure<E, D>
impl<E, D> Sync for FrameworkRequestFailure<E, D>
impl<E, D> Unpin for FrameworkRequestFailure<E, D>
impl<E, D> UnsafeUnpin for FrameworkRequestFailure<E, D>where
E: UnsafeUnpin,
D: UnsafeUnpin,
impl<E, D> UnwindSafe for FrameworkRequestFailure<E, D>where
E: UnwindSafe,
D: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more