Skip to content

Commit 1a2330d

Browse files
ldanilekConvex, Inc.
authored and
Convex, Inc.
committed
fix error propagation through ConvexValue serde (#25129)
unwrap the `anyhow::Error` in all public functions, and don't expose the internal `Error` type at all if we can help it (especially not for `Serialize` which is the thing that can throw bad_request errors). added regression test GitOrigin-RevId: e77c9774e3bcf3e492c68cc0c82b79e8688aa833
1 parent 1668ba3 commit 1a2330d

File tree

4 files changed

+33
-10
lines changed

4 files changed

+33
-10
lines changed

crates/value/src/serde/de.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -768,10 +768,18 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer {
768768
}
769769
}
770770

771-
pub fn from_value<T: DeserializeOwned>(value: ConvexValue) -> Result<T, Error> {
772-
T::deserialize(value)
771+
pub fn from_value<T: DeserializeOwned>(value: ConvexValue) -> anyhow::Result<T> {
772+
match T::deserialize(value) {
773+
Err(Error::Anyhow(e)) => Err(e),
774+
Err(e) => Err(e.into()),
775+
Ok(value) => Ok(value),
776+
}
773777
}
774778

775-
pub fn from_object<T: DeserializeOwned>(value: ConvexObject) -> Result<T, Error> {
776-
T::deserialize(ConvexValue::Object(value))
779+
pub fn from_object<T: DeserializeOwned>(value: ConvexObject) -> anyhow::Result<T> {
780+
match T::deserialize(ConvexValue::Object(value)) {
781+
Err(Error::Anyhow(e)) => Err(e),
782+
Err(e) => Err(e.into()),
783+
Ok(value) => Ok(value),
784+
}
777785
}

crates/value/src/serde/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ macro_rules! codegen_convex_serialization {
2727
type Error = anyhow::Error;
2828

2929
fn try_from(s: $struct) -> anyhow::Result<value::ConvexObject> {
30-
Ok(value::serde::to_object($serialized_struct::try_from(s)?)?)
30+
value::serde::to_object($serialized_struct::try_from(s)?)
3131
}
3232
}
3333

crates/value/src/serde/ser.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
};
2323

2424
#[derive(thiserror::Error)]
25-
pub enum Error {
25+
enum Error {
2626
#[error("Integer isn't in range for ConvexValue::Int64: {0:?}.")]
2727
IntegerOutofRange(#[from] TryFromIntError),
2828

@@ -668,10 +668,14 @@ impl serde::ser::SerializeStruct for SerializeObject {
668668
}
669669
}
670670

671-
pub fn to_value<T: Serialize>(value: T) -> Result<ConvexValue> {
672-
value.serialize(Serializer)
671+
pub fn to_value<T: Serialize>(value: T) -> anyhow::Result<ConvexValue> {
672+
match value.serialize(Serializer) {
673+
Err(Error::Anyhow(e)) => Err(e),
674+
Err(e) => Err(e.into()),
675+
Ok(value) => Ok(value),
676+
}
673677
}
674678

675-
pub fn to_object<T: Serialize>(value: T) -> Result<ConvexObject> {
676-
Ok(to_value(value)?.try_into()?)
679+
pub fn to_object<T: Serialize>(value: T) -> anyhow::Result<ConvexObject> {
680+
to_value(value)?.try_into()
677681
}

crates/value/src/serde/value.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,9 @@ impl<'de> Deserialize<'de> for FieldName {
192192

193193
#[cfg(test)]
194194
mod tests {
195+
use errors::ErrorMetadataAnyhowExt;
195196
use proptest::prelude::*;
197+
use serde_json::json;
196198

197199
use crate::{
198200
serde::{
@@ -225,4 +227,13 @@ mod tests {
225227
assert_eq!(start, deserialized);
226228
}
227229
}
230+
231+
#[test]
232+
fn test_error_metadata() {
233+
// Regression test, checking that error metadata is piped through.
234+
let big_json = json!("a".repeat(64_000_000));
235+
let serialize_result = to_value(big_json);
236+
let anyhow_err: anyhow::Error = serialize_result.unwrap_err();
237+
assert!(anyhow_err.is_bad_request());
238+
}
228239
}

0 commit comments

Comments
 (0)