From 0034e3bda82fb6bc772c73f87c1f3bb9624c5cef Mon Sep 17 00:00:00 2001 From: Luca Palmieri Date: Sun, 20 Jun 2021 19:03:48 +0100 Subject: [PATCH] Update to actix-web 4.0.0-beta.7. (#24) Add two new error types implementing ResponseError, as required, for our extractors. Add public docs for new errors. Co-authored-by: LukeMathWalker --- Cargo.toml | 4 +-- examples/custom-root-span/Cargo.toml | 2 +- examples/opentelemetry/Cargo.toml | 2 +- src/request_id.rs | 42 ++++++++++++++++++++++++++-- src/root_span.rs | 42 ++++++++++++++++++++++++++-- 5 files changed, 82 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f15be11db..44a60bec8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,8 @@ opentelemetry_0_13 = ["opentelemetry", "tracing-opentelemetry"] emit_event_on_error = [] [dependencies] -actix-web = "=4.0.0-beta.6" -actix-http = "=3.0.0-beta.6" +actix-web = "=4.0.0-beta.7" +actix-http = "=3.0.0-beta.7" actix-service = "^2.0.0" tracing = "0.1.19" tracing-futures = "0.2.4" diff --git a/examples/custom-root-span/Cargo.toml b/examples/custom-root-span/Cargo.toml index 57ae59f6b..befc4e325 100644 --- a/examples/custom-root-span/Cargo.toml +++ b/examples/custom-root-span/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -actix-web = "4.0.0-beta.6" +actix-web = "4.0.0-beta.7" opentelemetry = { version = "0.13", features = ["rt-tokio-current-thread"] } opentelemetry-jaeger = { version = "0.12", features = ["tokio"] } tracing-opentelemetry = { version = "0.12" } diff --git a/examples/opentelemetry/Cargo.toml b/examples/opentelemetry/Cargo.toml index f98392a69..8ac0b3cca 100644 --- a/examples/opentelemetry/Cargo.toml +++ b/examples/opentelemetry/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" license = "MIT/Apache-2.0" [dependencies] -actix-web = "=4.0.0-beta.6" +actix-web = "=4.0.0-beta.7" tracing = "0.1.19" opentelemetry = { version = "0.13", features = ["rt-tokio-current-thread"] } opentelemetry-jaeger = { version = "0.12", features = ["tokio"] } diff --git a/src/request_id.rs b/src/request_id.rs index 47d41f702..468698b13 100644 --- a/src/request_id.rs +++ b/src/request_id.rs @@ -1,5 +1,5 @@ use actix_web::dev::Payload; -use actix_web::{FromRequest, HttpRequest}; +use actix_web::{FromRequest, HttpRequest, ResponseError}; use std::future::{ready, Ready}; use uuid::Uuid; @@ -54,11 +54,47 @@ impl std::fmt::Display for RequestId { } } impl FromRequest for RequestId { - type Error = (); + type Error = RequestIdExtractionError; type Future = Ready>; type Config = (); fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { - ready(req.extensions().get::().copied().ok_or(())) + ready( + req.extensions() + .get::() + .copied() + .ok_or(RequestIdExtractionError { _priv: () }), + ) } } + +#[derive(Debug)] +/// Error returned by the [`RequestId`] extractor when it fails to retrieve +/// the current request id from request-local storage. +/// +/// It only happens if you try to extract the current request id without having +/// registered [`TracingLogger`] as a middleware for your application. +/// +/// [`TracingLogger`]: crate::TracingLogger +pub struct RequestIdExtractionError { + // It turns out that a unit struct has a public constructor! + // Therefore adding fields to it (either public or private) later on + // is an API breaking change. + // Therefore we are adding a dummy private field that the compiler is going + // to optimise away to make sure users cannot construct this error + // manually in their own code. + _priv: (), +} + +impl ResponseError for RequestIdExtractionError {} + +impl std::fmt::Display for RequestIdExtractionError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Failed to retrieve request id from request-local storage." + ) + } +} + +impl std::error::Error for RequestIdExtractionError {} diff --git a/src/root_span.rs b/src/root_span.rs index 4e09d8c37..804f7ad43 100644 --- a/src/root_span.rs +++ b/src/root_span.rs @@ -1,5 +1,5 @@ use actix_web::dev::Payload; -use actix_web::{FromRequest, HttpRequest}; +use actix_web::{FromRequest, HttpRequest, ResponseError}; use std::future::{ready, Ready}; use tracing::Span; @@ -47,11 +47,47 @@ impl std::convert::Into for RootSpan { } impl FromRequest for RootSpan { - type Error = (); + type Error = RootSpanExtractionError; type Future = Ready>; type Config = (); fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { - ready(req.extensions().get::().cloned().ok_or(())) + ready( + req.extensions() + .get::() + .cloned() + .ok_or(RootSpanExtractionError { _priv: () }), + ) } } + +#[derive(Debug)] +/// Error returned by the [`RootSpan`] extractor when it fails to retrieve +/// the root span from request-local storage. +/// +/// It only happens if you try to extract the root span without having +/// registered [`TracingLogger`] as a middleware for your application. +/// +/// [`TracingLogger`]: crate::TracingLogger +pub struct RootSpanExtractionError { + // It turns out that a unit struct has a public constructor! + // Therefore adding fields to it (either public or private) later on + // is an API breaking change. + // Therefore we are adding a dummy private field that the compiler is going + // to optimise away to make sure users cannot construct this error + // manually in their own code. + _priv: (), +} + +impl ResponseError for RootSpanExtractionError {} + +impl std::fmt::Display for RootSpanExtractionError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Failed to retrieve the root span from request-local storage." + ) + } +} + +impl std::error::Error for RootSpanExtractionError {}