routing/bedrock/
with_error_reporter.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use async_trait::async_trait;
6use router_error::RouterError;
7use sandbox::{CapabilityBound, Request, Routable, Router, RouterResponse};
8
9use crate::error::{ErrorReporter, RouteRequestErrorInfo};
10
11pub trait WithErrorReporter {
12    /// Returns a router that reports errors to `error_reporter`.
13    fn with_error_reporter(
14        self,
15        route_request: RouteRequestErrorInfo,
16        error_reporter: impl ErrorReporter,
17    ) -> Self;
18}
19
20struct RouterWithErrorReporter<T: CapabilityBound, R: ErrorReporter> {
21    router: Router<T>,
22    route_request: RouteRequestErrorInfo,
23    error_reporter: R,
24}
25
26#[async_trait]
27impl<T: CapabilityBound, R: ErrorReporter> Routable<T> for RouterWithErrorReporter<T, R> {
28    async fn route(
29        &self,
30        request: Option<Request>,
31        debug: bool,
32    ) -> Result<RouterResponse<T>, RouterError> {
33        let target = request.as_ref().map(|r| r.target.clone());
34        match self.router.route(request, debug).await {
35            Ok(res) => Ok(res),
36            Err(err) => {
37                self.error_reporter.report(&self.route_request, &err, target).await;
38                Err(err)
39            }
40        }
41    }
42}
43
44impl<T: CapabilityBound> WithErrorReporter for Router<T> {
45    fn with_error_reporter(
46        self,
47        route_request: RouteRequestErrorInfo,
48        error_reporter: impl ErrorReporter,
49    ) -> Self {
50        Self::new(RouterWithErrorReporter { router: self, route_request, error_reporter })
51    }
52}