Skip to content

Commit 47ed9d3

Browse files
authored
feat: Expose recover error service (#2159)
1 parent dcaa679 commit 47ed9d3

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

tonic/src/service/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ pub use self::layered::{LayerExt, Layered};
1313
pub use self::router::{Routes, RoutesBuilder};
1414
#[cfg(feature = "router")]
1515
pub use axum::{body::Body as AxumBody, Router as AxumRouter};
16+
17+
pub mod recover_error;
18+
pub use self::recover_error::{RecoverError, RecoverErrorLayer};

tonic/src/transport/server/service/recover_error.rs renamed to tonic/src/service/recover_error.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,50 @@
1+
//! Middleware which recovers from error.
2+
13
use std::{
4+
fmt,
25
future::Future,
36
pin::Pin,
47
task::{ready, Context, Poll},
58
};
69

710
use http::Response;
811
use pin_project::pin_project;
12+
use tower_layer::Layer;
913
use tower_service::Service;
1014

1115
use crate::Status;
1216

17+
/// Layer which applies the [`RecoverError`] middleware.
18+
#[derive(Debug, Default, Clone)]
19+
pub struct RecoverErrorLayer {
20+
_priv: (),
21+
}
22+
23+
impl RecoverErrorLayer {
24+
/// Create a new `RecoverErrorLayer`.
25+
pub fn new() -> Self {
26+
Self { _priv: () }
27+
}
28+
}
29+
30+
impl<S> Layer<S> for RecoverErrorLayer {
31+
type Service = RecoverError<S>;
32+
33+
fn layer(&self, inner: S) -> Self::Service {
34+
RecoverError::new(inner)
35+
}
36+
}
37+
1338
/// Middleware that attempts to recover from service errors by turning them into a response built
1439
/// from the `Status`.
1540
#[derive(Debug, Clone)]
16-
pub(crate) struct RecoverError<S> {
41+
pub struct RecoverError<S> {
1742
inner: S,
1843
}
1944

2045
impl<S> RecoverError<S> {
21-
pub(crate) fn new(inner: S) -> Self {
46+
/// Create a new `RecoverError` middleware.
47+
pub fn new(inner: S) -> Self {
2248
Self { inner }
2349
}
2450
}
@@ -43,12 +69,19 @@ where
4369
}
4470
}
4571

72+
/// Response future for [`RecoverError`].
4673
#[pin_project]
47-
pub(crate) struct ResponseFuture<F> {
74+
pub struct ResponseFuture<F> {
4875
#[pin]
4976
inner: F,
5077
}
5178

79+
impl<F> fmt::Debug for ResponseFuture<F> {
80+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81+
f.debug_struct("ResponseFuture").finish()
82+
}
83+
}
84+
5285
impl<F, E, ResBody> Future for ResponseFuture<F>
5386
where
5487
F: Future<Output = Result<Response<ResBody>, E>>,
@@ -74,12 +107,19 @@ where
74107
}
75108
}
76109

110+
/// Response body for [`RecoverError`].
77111
#[pin_project]
78-
pub(crate) struct ResponseBody<B> {
112+
pub struct ResponseBody<B> {
79113
#[pin]
80114
inner: Option<B>,
81115
}
82116

117+
impl<B> fmt::Debug for ResponseBody<B> {
118+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119+
f.debug_struct("ResponseBody").finish()
120+
}
121+
}
122+
83123
impl<B> ResponseBody<B> {
84124
fn full(inner: B) -> Self {
85125
Self { inner: Some(inner) }

tonic/src/transport/server/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ pub use incoming::TcpIncoming;
4141
#[cfg(feature = "_tls-any")]
4242
use crate::transport::Error;
4343

44-
use self::service::{ConnectInfoLayer, RecoverError, ServerIo};
44+
use self::service::{ConnectInfoLayer, ServerIo};
4545
use super::service::GrpcTimeout;
4646
use crate::body::Body;
47+
use crate::service::RecoverErrorLayer;
4748
use bytes::Bytes;
4849
use http::{Request, Response};
4950
use http_body_util::BodyExt;
@@ -1087,7 +1088,7 @@ where
10871088
let trace_interceptor = self.trace_interceptor.clone();
10881089

10891090
let svc = ServiceBuilder::new()
1090-
.layer_fn(RecoverError::new)
1091+
.layer(RecoverErrorLayer::new())
10911092
.option_layer(concurrency_limit.map(ConcurrencyLimitLayer::new))
10921093
.layer_fn(|s| GrpcTimeout::new(s, timeout))
10931094
.service(svc);

tonic/src/transport/server/service/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
mod io;
22
pub(crate) use self::io::{ConnectInfoLayer, ServerIo};
33

4-
mod recover_error;
5-
pub(crate) use self::recover_error::RecoverError;
6-
74
#[cfg(feature = "_tls-any")]
85
mod tls;
96
#[cfg(feature = "_tls-any")]

0 commit comments

Comments
 (0)