Skip to main content

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    /// Performance monitoring transactions carrying spans.
40    Transaction,
41    /// User feedback payload.
42    ///
43    /// TODO(Jferg): Change this to UserFeedback once old UserReport logic is deprecated.
44    UserReportV2,
45    /// All events that do not qualify as any other type.
46    #[serde(other)]
47    #[default]
48    Default,
49}
50
51impl EventType {
52    /// Returns the string representation of this event type.
53    pub fn as_str(&self) -> &'static str {
54        match self {
55            EventType::Default => "default",
56            EventType::Error => "error",
57            EventType::Csp => "csp",
58            EventType::Hpkp => "hpkp",
59            EventType::ExpectCt => "expectct",
60            EventType::ExpectStaple => "expectstaple",
61            EventType::Transaction => "transaction",
62            EventType::UserReportV2 => "feedback",
63        }
64    }
65}
66
67/// An error used when parsing `EventType`.
68#[derive(Clone, Copy, Debug)]
69pub struct ParseEventTypeError;
70
71impl fmt::Display for ParseEventTypeError {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        write!(f, "invalid event type")
74    }
75}
76
77impl std::error::Error for ParseEventTypeError {}
78
79impl FromStr for EventType {
80    type Err = ParseEventTypeError;
81
82    fn from_str(string: &str) -> Result<Self, Self::Err> {
83        Ok(match string {
84            "default" => EventType::Default,
85            "error" => EventType::Error,
86            "csp" => EventType::Csp,
87            "hpkp" => EventType::Hpkp,
88            "expectct" => EventType::ExpectCt,
89            "expectstaple" => EventType::ExpectStaple,
90            "transaction" => EventType::Transaction,
91            "feedback" => EventType::UserReportV2,
92            _ => return Err(ParseEventTypeError),
93        })
94    }
95}
96
97impl fmt::Display for EventType {
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        write!(f, "{}", self.as_str())
100    }
101}
102
103impl Empty for EventType {
104    #[inline]
105    fn is_empty(&self) -> bool {
106        false
107    }
108}
109
110impl FromValue for EventType {
111    fn from_value(value: Annotated<Value>) -> Annotated<Self> {
112        match String::from_value(value) {
113            Annotated(Some(value), mut meta) => match value.parse() {
114                Ok(eventtype) => Annotated(Some(eventtype), meta),
115                Err(_) => {
116                    meta.add_error(ErrorKind::InvalidData);
117                    meta.set_original_value(Some(value));
118                    Annotated(None, meta)
119                }
120            },
121            Annotated(None, meta) => Annotated(None, meta),
122        }
123    }
124}
125
126impl IntoValue for EventType {
127    fn into_value(self) -> Value
128    where
129        Self: Sized,
130    {
131        Value::String(self.to_string())
132    }
133
134    fn serialize_payload<S>(&self, s: S, _behavior: SkipSerialization) -> Result<S::Ok, S::Error>
135    where
136        Self: Sized,
137        S: serde::Serializer,
138    {
139        Serialize::serialize(self.as_str(), s)
140    }
141}