routing/
error_logging_router.rs1use crate::error::{ErrorReporter, RouteRequestErrorInfo};
6use async_trait::async_trait;
7use capability_source::CapabilitySource;
8use fidl_fuchsia_component_runtime::RouteRequest;
9use router_error::RouterError;
10use runtime_capabilities::{
11 Capability, CapabilityBound, Connector, Data, Dictionary, DirConnector, Routable, Router,
12 WeakInstanceToken,
13};
14use std::sync::Arc;
15
16pub struct ErrorLoggingRouter<R: ErrorReporter> {
17 inner_router: Capability,
18 route_request: RouteRequestErrorInfo,
19 error_reporter: R,
20 error_location: Arc<WeakInstanceToken>,
21}
22
23impl<R: ErrorReporter> ErrorLoggingRouter<R> {
24 pub fn new(
25 inner_router: Capability,
26 route_request: impl Into<RouteRequestErrorInfo>,
27 error_reporter: R,
28 error_location: Arc<WeakInstanceToken>,
29 ) -> Capability {
30 match &inner_router {
31 Capability::ConnectorRouter(_) => Router::<Connector>::new(Self {
32 inner_router,
33 route_request: route_request.into(),
34 error_reporter,
35 error_location,
36 })
37 .into(),
38 Capability::DirConnectorRouter(_) => Router::<DirConnector>::new(Self {
39 inner_router,
40 route_request: route_request.into(),
41 error_reporter,
42 error_location,
43 })
44 .into(),
45 Capability::DictionaryRouter(_) => Router::<Dictionary>::new(Self {
46 inner_router,
47 route_request: route_request.into(),
48 error_reporter,
49 error_location,
50 })
51 .into(),
52 Capability::DataRouter(_) => Router::<Data>::new(Self {
53 inner_router,
54 route_request: route_request.into(),
55 error_reporter,
56 error_location,
57 })
58 .into(),
59 _ => panic!("non-router type passed to ErrorLoggingRouter"),
60 }
61 }
62}
63
64#[async_trait]
65impl<T: CapabilityBound, R: ErrorReporter> Routable<T> for ErrorLoggingRouter<R>
66where
67 Arc<Router<T>>: TryFrom<Capability>,
68{
69 async fn route(
70 &self,
71 request: RouteRequest,
72 target: Arc<WeakInstanceToken>,
73 ) -> Result<Option<Arc<T>>, RouterError> {
74 let inner_router: Arc<Router<T>> =
75 self.inner_router.clone().try_into().ok().expect("type mismatch");
76 match inner_router.route(request, target).await {
77 Ok(res) => Ok(res),
78 Err(err) => {
79 self.error_reporter
80 .report(&self.route_request, &err, self.error_location.clone())
81 .await;
82 Err(err)
83 }
84 }
85 }
86
87 async fn route_debug(
88 &self,
89 request: RouteRequest,
90 target: Arc<WeakInstanceToken>,
91 ) -> Result<CapabilitySource, RouterError> {
92 let inner_router: Arc<Router<T>> =
93 self.inner_router.clone().try_into().ok().expect("type mismatch");
94 match inner_router.route_debug(request, target).await {
95 Ok(res) => Ok(res),
96 Err(err) => {
97 self.error_reporter
98 .report(&self.route_request, &err, self.error_location.clone())
99 .await;
100 Err(err)
101 }
102 }
103 }
104}