relay_base_schema/
events.rs

1//! Defines types related to Sentry events.
2//!
3//! As opposed to the event protocol defined in `relay-event-schema`, these types are meant to be
4//! used outside of the event protocol, for instance to reference Events from other places.
5
6use std::fmt;
7use std::str::FromStr;
8
9use relay_protocol::{Annotated, Empty, ErrorKind, FromValue, IntoValue, SkipSerialization, Value};
10use serde::{Deserialize, Serialize};
11
12/// The type of an event.
13///
14/// The event type determines how Sentry handles the event and has an impact on processing, rate
15/// limiting, and quotas. There are three fundamental classes of event types:
16///
17///  - **Error monitoring events** (`default`, `error`): Processed and grouped into unique issues
18///    based on their exception stack traces and error messages.
19///  - **Security events** (`csp`, `hpkp`, `expectct`, `expectstaple`): Derived from Browser
20///    security violation reports and grouped into unique issues based on the endpoint and
21///    violation. SDKs do not send such events.
22///  - **Transaction events** (`transaction`): Contain operation spans and collected into traces for
23///    performance monitoring.
24#[derive(
25    Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, Serialize, Default,
26)]
27#[serde(rename_all = "lowercase")]
28pub enum EventType {
29    /// Events that carry an exception payload.
30    Error,
31    /// A CSP violation payload.
32    Csp,
33    /// An HPKP violation payload.
34    Hpkp,
35    /// An ExpectCT violation payload.
36    ExpectCt,
37    /// An ExpectStaple violation payload.
38    ExpectStaple,
39    /// Network Error Logging report.
40    Nel,
41    /// Performance monitoring transactions carrying spans.
42    Transaction,
43    /// User feedback payload.
44    ///
45    /// TODO(Jferg): Change this to UserFeedback once old UserReport logic is deprecated.
46    UserReportV2,
47    /// All events that do not qualify as any other type.
48    #[serde(other)]
49    #[default]
50    Default,
51}
52
53impl EventType {
54    /// Returns the string representation of this event type.
55    pub fn as_str(&self) -> &'static str {
56        match self {
57            EventType::Default => "default",
58            EventType::Error => "error",
59            EventType::Csp => "csp",
60            EventType::Hpkp => "hpkp",
61            EventType::ExpectCt => "expectct",
62            EventType::ExpectStaple => "expectstaple",
63            EventType::Nel => "nel",
64            EventType::Transaction => "transaction",
65            EventType::UserReportV2 => "feedback",
66        }
67    }
68}
69
70/// An error used when parsing `EventType`.
71#[derive(Clone, Copy, Debug)]
72pub struct ParseEventTypeError;
73
74impl fmt::Display for ParseEventTypeError {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        write!(f, "invalid event type")
77    }
78}
79
80impl std::error::Error for ParseEventTypeError {}
81
82impl FromStr for EventType {
83    type Err = ParseEventTypeError;
84
85    fn from_str(string: &str) -> Result<Self, Self::Err> {
86        Ok(match string {
87            "default" => EventType::Default,
88            "error" => EventType::Error,
89            "csp" => EventType::Csp,
90            "hpkp" => EventType::Hpkp,
91            "expectct" => EventType::ExpectCt,
92            "expectstaple" => EventType::ExpectStaple,
93            "nel" => EventType::Nel,
94            "transaction" => EventType::Transaction,
95            "feedback" => EventType::UserReportV2,
96            _ => return Err(ParseEventTypeError),
97        })
98    }
99}
100
101impl fmt::Display for EventType {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        write!(f, "{}", self.as_str())
104    }
105}
106
107impl Empty for EventType {
108    #[inline]
109    fn is_empty(&self) -> bool {
110        false
111    }
112}
113
114impl FromValue for EventType {
115    fn from_value(value: Annotated<Value>) -> Annotated<Self> {
116        match String::from_value(value) {
117            Annotated(Some(value), mut meta) => match value.parse() {
118                Ok(eventtype) => Annotated(Some(eventtype), meta),
119                Err(_) => {
120                    meta.add_error(ErrorKind::InvalidData);
121                    meta.set_original_value(Some(value));
122                    Annotated(None, meta)
123                }
124            },
125            Annotated(None, meta) => Annotated(None, meta),
126        }
127    }
128}
129
130impl IntoValue for EventType {
131    fn into_value(self) -> Value
132    where
133        Self: Sized,
134    {
135        Value::String(self.to_string())
136    }
137
138    fn serialize_payload<S>(&self, s: S, _behavior: SkipSerialization) -> Result<S::Ok, S::Error>
139    where
140        Self: Sized,
141        S: serde::Serializer,
142    {
143        Serialize::serialize(self.as_str(), s)
144    }
145}