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`): Derived from Browser security violation reports and grouped into
20///    unique issues based on the endpoint and violation. SDKs do not send such events.
21///  - **Transaction events** (`transaction`): Contain operation spans and collected into traces for
22///    performance monitoring.
23#[derive(
24    Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, Serialize, Default,
25)]
26#[serde(rename_all = "lowercase")]
27pub enum EventType {
28    /// Events that carry an exception payload.
29    Error,
30    /// A CSP violation payload.
31    Csp,
32    /// Performance monitoring transactions carrying spans.
33    Transaction,
34    /// User feedback payload.
35    ///
36    /// TODO(Jferg): Change this to UserFeedback once old UserReport logic is deprecated.
37    UserReportV2,
38    /// All events that do not qualify as any other type.
39    #[serde(other)]
40    #[default]
41    Default,
42}
43
44impl EventType {
45    /// Returns the string representation of this event type.
46    pub fn as_str(&self) -> &'static str {
47        match self {
48            EventType::Default => "default",
49            EventType::Error => "error",
50            EventType::Csp => "csp",
51            EventType::Transaction => "transaction",
52            EventType::UserReportV2 => "feedback",
53        }
54    }
55}
56
57/// An error used when parsing `EventType`.
58#[derive(Clone, Copy, Debug)]
59pub struct ParseEventTypeError;
60
61impl fmt::Display for ParseEventTypeError {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        write!(f, "invalid event type")
64    }
65}
66
67impl std::error::Error for ParseEventTypeError {}
68
69impl FromStr for EventType {
70    type Err = ParseEventTypeError;
71
72    fn from_str(string: &str) -> Result<Self, Self::Err> {
73        Ok(match string {
74            "default" => EventType::Default,
75            "error" => EventType::Error,
76            "csp" => EventType::Csp,
77            "transaction" => EventType::Transaction,
78            "feedback" => EventType::UserReportV2,
79            _ => return Err(ParseEventTypeError),
80        })
81    }
82}
83
84impl fmt::Display for EventType {
85    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        write!(f, "{}", self.as_str())
87    }
88}
89
90impl Empty for EventType {
91    #[inline]
92    fn is_empty(&self) -> bool {
93        false
94    }
95}
96
97impl FromValue for EventType {
98    fn from_value(value: Annotated<Value>) -> Annotated<Self> {
99        match String::from_value(value) {
100            Annotated(Some(value), mut meta) => match value.parse() {
101                Ok(eventtype) => Annotated(Some(eventtype), meta),
102                Err(_) => {
103                    meta.add_error(ErrorKind::InvalidData);
104                    meta.set_original_value(Some(value));
105                    Annotated(None, meta)
106                }
107            },
108            Annotated(None, meta) => Annotated(None, meta),
109        }
110    }
111}
112
113impl IntoValue for EventType {
114    fn into_value(self) -> Value
115    where
116        Self: Sized,
117    {
118        Value::String(self.to_string())
119    }
120
121    fn serialize_payload<S>(&self, s: S, _behavior: SkipSerialization) -> Result<S::Ok, S::Error>
122    where
123        Self: Sized,
124        S: serde::Serializer,
125    {
126        Serialize::serialize(self.as_str(), s)
127    }
128}