Trait tower_http::classify::ClassifyResponse

source ·
pub trait ClassifyResponse {
    type FailureClass;
    type ClassifyEos: ClassifyEos<FailureClass = Self::FailureClass>;

    // Required methods
    fn classify_response<B>(
        self,
        res: &Response<B>
    ) -> ClassifiedResponse<Self::FailureClass, Self::ClassifyEos>;
    fn classify_error<E>(self, error: &E) -> Self::FailureClass
       where E: Display + 'static;

    // Provided method
    fn map_failure_class<F, NewClass>(self, f: F) -> MapFailureClass<Self, F>
       where Self: Sized,
             F: FnOnce(Self::FailureClass) -> NewClass { ... }
}
Expand description

Trait for classifying responses as either success or failure. Designed to support both unary requests (single request for a single response) as well as streaming responses.

Response classifiers are used in cases where middleware needs to determine whether a response completed successfully or failed. For example, they may be used by logging or metrics middleware to record failures differently from successes.

Furthermore, when a response fails, a response classifier may provide additional information about the failure. This can, for example, be used to build retry policies by indicating whether or not a particular failure is retryable.

Required Associated Types§

source

type FailureClass

The type returned when a response is classified as a failure.

Depending on the classifier, this may simply indicate that the request failed, or it may contain additional information about the failure, such as whether or not it is retryable.

source

type ClassifyEos: ClassifyEos<FailureClass = Self::FailureClass>

The type used to classify the response end of stream (EOS).

Required Methods§

source

fn classify_response<B>( self, res: &Response<B> ) -> ClassifiedResponse<Self::FailureClass, Self::ClassifyEos>

Attempt to classify the beginning of a response.

In some cases, the response can be classified immediately, without waiting for a body to complete. This may include:

  • When the response has an error status code.
  • When a successful response does not have a streaming body.
  • When the classifier does not care about streaming bodies.

When the response can be classified immediately, classify_response returns a ClassifiedResponse::Ready which indicates whether the response succeeded or failed.

In other cases, however, the classifier may need to wait until the response body stream completes before it can classify the response. For example, gRPC indicates RPC failures using the grpc-status trailer. In this case, classify_response returns a ClassifiedResponse::RequiresEos containing a type which will be used to classify the response when the body stream ends.

source

fn classify_error<E>(self, error: &E) -> Self::FailureClass
where E: Display + 'static,

Classify an error.

Errors are always errors (doh) but sometimes it might be useful to have multiple classes of errors. A retry policy might allow retrying some errors and not others.

Provided Methods§

source

fn map_failure_class<F, NewClass>(self, f: F) -> MapFailureClass<Self, F>
where Self: Sized, F: FnOnce(Self::FailureClass) -> NewClass,

Transform the failure classification using a function.

§Example
use tower_http::classify::{
    ServerErrorsAsFailures, ServerErrorsFailureClass,
    ClassifyResponse, ClassifiedResponse
};
use http::{Response, StatusCode};
use http_body::Empty;
use bytes::Bytes;

fn transform_failure_class(class: ServerErrorsFailureClass) -> NewFailureClass {
    match class {
        // Convert status codes into u16
        ServerErrorsFailureClass::StatusCode(status) => {
            NewFailureClass::Status(status.as_u16())
        }
        // Don't change errors.
        ServerErrorsFailureClass::Error(error) => {
            NewFailureClass::Error(error)
        }
    }
}

enum NewFailureClass {
    Status(u16),
    Error(String),
}

// Create a classifier who's failure class will be transformed by `transform_failure_class`
let classifier = ServerErrorsAsFailures::new().map_failure_class(transform_failure_class);

let response = Response::builder()
    .status(StatusCode::INTERNAL_SERVER_ERROR)
    .body(Empty::<Bytes>::new())
    .unwrap();

let classification = classifier.classify_response(&response);

assert!(matches!(
    classification,
    ClassifiedResponse::Ready(Err(NewFailureClass::Status(500)))
));

Object Safety§

This trait is not object safe.

Implementors§