rama::http::layer::classify

Trait ClassifyResponse

pub trait ClassifyResponse:
    Send
    + Sync
    + 'static {
    type FailureClass: Send + Sync + 'static;
    type ClassifyEos: ClassifyEos<FailureClass = Self::FailureClass> + Send + Sync + 'static;

    // 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;

    // 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§

type FailureClass: Send + Sync + 'static

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.

type ClassifyEos: ClassifyEos<FailureClass = Self::FailureClass> + Send + Sync + 'static

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

Required Methods§

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.

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

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§

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 rama_http::layer::classify::{
    ServerErrorsAsFailures, ServerErrorsFailureClass,
    ClassifyResponse, ClassifiedResponse
};
use http::{Response, StatusCode};
use http_body_util::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§