Skip to content

Commit d8657a2

Browse files
committed
ref(general): Streamline the use of lenient and JSON strings
1 parent 72ff135 commit d8657a2

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

general/src/protocol/logentry.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::protocol::LenientString;
1+
use crate::protocol::JsonLenientString;
22
use crate::types::{Annotated, Array, FromValue, Object, Value};
33

44
/// A log entry message.
@@ -32,7 +32,7 @@ impl FromValue for LogEntry {
3232
// add the former as the 'formatted' attribute of the latter.
3333
// See GH-3248
3434
match value {
35-
x @ Annotated(Some(Value::Object(_)), _) | x @ Annotated(None, _) => {
35+
x @ Annotated(Some(Value::Object(_)), _) => {
3636
#[derive(Debug, FromValue)]
3737
struct Helper {
3838
message: Annotated<String>,
@@ -56,9 +56,13 @@ impl FromValue for LogEntry {
5656
},
5757
)
5858
}
59+
Annotated(None, meta) => Annotated(None, meta),
60+
// The next two cases handle the legacy top-level `message` attribute, which was sent as
61+
// literal string, false (which should be ignored) or even as deep JSON object. Sentry
62+
// historically JSONified this field.
5963
Annotated(Some(Value::Bool(false)), _) => Annotated(None, Default::default()),
6064
x => Annotated::new(LogEntry {
61-
formatted: LenientString::from_value(x).map_value(|x| x.into_inner()),
65+
formatted: JsonLenientString::from_value(x).map_value(|x| x.into_inner()),
6266
..Default::default()
6367
}),
6468
}

general/src/protocol/types.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,10 @@ impl FromValue for JsonLenientString {
594594
fn from_value(value: Annotated<Value>) -> Annotated<Self> {
595595
match value {
596596
Annotated(Some(Value::String(string)), meta) => Annotated(Some(string.into()), meta),
597+
Annotated(Some(other), meta) => {
598+
Annotated(Some(serde_json::to_string(&other).unwrap().into()), meta)
599+
}
597600
Annotated(None, meta) => Annotated(None, meta),
598-
x => Annotated(Some(x.payload_to_json().unwrap().into()), x.1),
599601
}
600602
}
601603
}

general/src/protocol/user.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::protocol::{IpAddr, JsonLenientString};
1+
use crate::protocol::{IpAddr, LenientString};
22
use crate::types::{Annotated, Object, Value};
33

44
/// Geographical location of the end user or device.
@@ -28,7 +28,7 @@ pub struct Geo {
2828
pub struct User {
2929
/// Unique identifier of the user.
3030
#[metastructure(pii = "true", max_chars = "enumlike")]
31-
pub id: Annotated<JsonLenientString>,
31+
pub id: Annotated<LenientString>,
3232

3333
/// Email address of the user.
3434
#[metastructure(pii = "true", max_chars = "email", match_regex = r"@")]
@@ -143,6 +143,34 @@ fn test_user_roundtrip() {
143143
assert_eq_str!(json, user.to_json_pretty().unwrap());
144144
}
145145

146+
#[test]
147+
fn test_user_lenient_id() {
148+
let input = r#"{"id":42}"#;
149+
let output = r#"{"id":"42"}"#;
150+
let user = Annotated::new(User {
151+
id: Annotated::new("42".to_string().into()),
152+
..User::default()
153+
});
154+
155+
assert_eq_dbg!(user, Annotated::from_json(input).unwrap());
156+
assert_eq_str!(output, user.to_json().unwrap());
157+
}
158+
159+
#[test]
160+
fn test_user_invalid_id() {
161+
use crate::types::Error;
162+
let json = r#"{"id":[]}"#;
163+
let user = Annotated::new(User {
164+
id: Annotated::from_error(
165+
Error::expected("primitive value"),
166+
Some(Value::Array(vec![])),
167+
),
168+
..User::default()
169+
});
170+
171+
assert_eq_dbg!(user, Annotated::from_json(json).unwrap());
172+
}
173+
146174
#[test]
147175
fn test_explicit_none() {
148176
let json = r#"{

0 commit comments

Comments
 (0)