From 2febc0370d089780c528b47aa5d1dc9d0fd7d82f Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 12 Jul 2021 16:30:08 +0300 Subject: [PATCH 1/3] feat: add SpanStatus enum --- sentry-types/src/protocol/v7.rs | 111 +++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index 75ac12bff..198bd434a 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1275,7 +1275,7 @@ pub struct TraceContext { pub description: Option, /// Describes the status of the span (e.g. `ok`, `cancelled`, etc.) #[serde(default, skip_serializing_if = "Option::is_none")] - pub status: Option, + pub status: Option, } macro_rules! into_context { @@ -1546,7 +1546,7 @@ pub struct Span { pub start_timestamp: DateTime, /// Describes the status of the span (e.g. `ok`, `cancelled`, etc.) #[serde(default, skip_serializing_if = "Option::is_none")] - pub status: Option, + pub status: Option, /// Optional tags to be attached to the span. #[serde(default, skip_serializing_if = "Map::is_empty")] pub tags: Map, @@ -1595,6 +1595,113 @@ impl fmt::Display for Span { } } +/// The status of a Span. +#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum SpanStatus { + /// The operation completed successfully. + #[serde(rename = "ok")] + Ok, + /// Deadline expired before operation could complete. + #[serde(rename = "deadline_exceeded")] + DeadlineExceeded, + /// 401 Unauthorized (actually does mean unauthenticated according to RFC 7235) + #[serde(rename = "unauthenticated")] + Unauthenticated, + /// 403 Forbidden + #[serde(rename = "permission_denied")] + PermissionDenied, + /// 404 Not Found. Some requested entity (file or directory) was not found. + #[serde(rename = "not_found")] + NotFound, + /// 429 Too Many Requests + #[serde(rename = "resource_exhausted")] + ResourceExhausted, + /// Client specified an invalid argument. 4xx. + #[serde(rename = "invalid_argument")] + InvalidArgument, + /// 501 Not Implemented + #[serde(rename = "unimplemented")] + Unimplemented, + /// 503 Service Unavailable + #[serde(rename = "unavailable")] + Unavailable, + /// Other/generic 5xx. + #[serde(rename = "internal_error")] + InternalError, + /// Unknown. Any non-standard HTTP status code. + #[serde(rename = "unknown_error")] + UnknownError, + /// The operation was cancelled (typically by the user). + #[serde(rename = "cancelled")] + Cancelled, + /// Already exists (409) + #[serde(rename = "already_exists")] + AlreadyExists, + /// Operation was rejected because the system is not in a state required for the operation's + #[serde(rename = "failed_precondition")] + FailedPrecondition, + /// The operation was aborted, typically due to a concurrency issue. + #[serde(rename = "aborted")] + Aborted, + /// Operation was attempted past the valid range. + #[serde(rename = "out_of_range")] + OutOfRange, + /// Unrecoverable data loss or corruption + #[serde(rename = "data_loss")] + DataLoss, +} + +impl str::FromStr for SpanStatus { + type Err = ParseLevelError; + + fn from_str(s: &str) -> Result { + Ok(match s { + "ok" => SpanStatus::Ok, + "deadline_exceeded" => SpanStatus::DeadlineExceeded, + "unauthenticated" => SpanStatus::Unauthenticated, + "permission_denied" => SpanStatus::PermissionDenied, + "not_found" => SpanStatus::NotFound, + "resource_exhausted" => SpanStatus::ResourceExhausted, + "invalid_argument" => SpanStatus::InvalidArgument, + "unimplemented" => SpanStatus::Unimplemented, + "unavailable" => SpanStatus::Unavailable, + "internal_error" => SpanStatus::InternalError, + "unknown_error" => SpanStatus::UnknownError, + "cancelled" => SpanStatus::Cancelled, + "already_exists" => SpanStatus::AlreadyExists, + "failed_precondition" => SpanStatus::FailedPrecondition, + "aborted" => SpanStatus::Aborted, + "out_of_range" => SpanStatus::OutOfRange, + "data_loss" => SpanStatus::DataLoss, + _ => return Err(ParseLevelError), + }) + } +} + +impl fmt::Display for SpanStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + SpanStatus::Ok => write!(f, "ok"), + SpanStatus::DeadlineExceeded => write!(f, "deadline_exceeded"), + SpanStatus::Unauthenticated => write!(f, "unauthenticated"), + SpanStatus::PermissionDenied => write!(f, "permission_denied"), + SpanStatus::NotFound => write!(f, "not_found"), + SpanStatus::ResourceExhausted => write!(f, "resource_exhausted"), + SpanStatus::InvalidArgument => write!(f, "invalid_argument"), + SpanStatus::Unimplemented => write!(f, "unimplemented"), + SpanStatus::Unavailable => write!(f, "unavailable"), + SpanStatus::InternalError => write!(f, "internal_error"), + SpanStatus::UnknownError => write!(f, "unknown_error"), + SpanStatus::Cancelled => write!(f, "cancelled"), + SpanStatus::AlreadyExists => write!(f, "already_exists"), + SpanStatus::FailedPrecondition => write!(f, "failed_precondition"), + SpanStatus::Aborted => write!(f, "aborted"), + SpanStatus::OutOfRange => write!(f, "out_of_range"), + SpanStatus::DataLoss => write!(f, "data_loss"), + } + } +} + /// Represents a tracing transaction. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Transaction<'a> { From f60071a0dc613b69be4b0de88d84405a8a8f6fb7 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 12 Jul 2021 17:15:46 +0300 Subject: [PATCH 2/3] fix: add non_exhaustive attribute to SpanStatus --- sentry-types/src/protocol/v7.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index 198bd434a..e11db46bc 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1597,6 +1597,7 @@ impl fmt::Display for Span { /// The status of a Span. #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[non_exhaustive] pub enum SpanStatus { /// The operation completed successfully. #[serde(rename = "ok")] From f8ff5a24eabda5071876d0689a35333407a7f838 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 12 Jul 2021 18:01:41 +0300 Subject: [PATCH 3/3] fix: Add ParseStatusError and use it when parsing SpanStatus --- sentry-types/src/protocol/v7.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index e11db46bc..1c59e3e13 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1595,6 +1595,11 @@ impl fmt::Display for Span { } } +/// An error used when parsing `SpanStatus`. +#[derive(Debug, Error)] +#[error("invalid status")] +pub struct ParseStatusError; + /// The status of a Span. #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash)] #[non_exhaustive] @@ -1653,7 +1658,7 @@ pub enum SpanStatus { } impl str::FromStr for SpanStatus { - type Err = ParseLevelError; + type Err = ParseStatusError; fn from_str(s: &str) -> Result { Ok(match s { @@ -1674,7 +1679,7 @@ impl str::FromStr for SpanStatus { "aborted" => SpanStatus::Aborted, "out_of_range" => SpanStatus::OutOfRange, "data_loss" => SpanStatus::DataLoss, - _ => return Err(ParseLevelError), + _ => return Err(ParseStatusError), }) } }