error.rs
Overview
The [error.rs](/projects/287/67737) file defines and implements error handling related to serialization processes within the system, specifically targeting scenarios encountered during JSON serialization. It declares the `SerializeError` enum representing various serialization error cases, and implements the `Display` trait for human-readable error messages. This file plays a crucial role in providing detailed, context-aware error descriptions that assist in debugging and error reporting when serialization fails.
Detailed Explanation
Enum: SerializeError
`SerializeError` is an enumeration encapsulating all possible errors that can arise during serialization. Each variant corresponds to a specific serialization error condition.
Variants
DatetimeLibraryUnsupported
Indicates the datetime timezone library used is unsupported.
Message: "datetime's timezone library is not supported: use datetime.timezone.utc, pendulum, pytz, or dateutil"DefaultRecursionLimit
The serializer has exceeded the default recursion limit during serialization.
Message: "default serializer exceeds recursion limit"Integer53Bits
An integer value exceeds the 53-bit range supported by JSON numbers.
Message: "Integer exceeds 53-bit range"Integer64Bits
An integer value exceeds the 64-bit range.
Message: "Integer exceeds 64-bit range"InvalidStr
The string value is invalid according to internal project constraints (message sourced fromcrate::util::INVALID_STR).
Message: Value ofcrate::util::INVALID_STRInvalidFragment
An orjson.Fragment content is neither bytes nor string type.
Message: "orjson.Fragment's content is not of type bytes or str"KeyMustBeStr
Dictionary keys must be strings, but a non-string key was encountered.
Message: "Dict key must be str"RecursionLimit
Recursion depth exceeded a set limit during serialization.
Message: "Recursion limit reached"TimeHasTzinfo
datetime.time object has timezone info set, which is not supported.
Message: "datetime.time must not have tzinfo set"DictIntegerKey64Bit
Integer keys in dictionaries must fit within 64-bit integer range.
Message: "Dict integer key must be within 64-bit range"DictKeyInvalidType
Dictionary key has an invalid type, not serializable withOPT_NON_STR_KEYS.
Message: "Dict key must a type serializable with OPT_NON_STR_KEYS"NumpyMalformed
The numpy array is malformed.
Message: "numpy array is malformed"NumpyNotCContiguous
Numpy array is not C contiguous in memory.
Message: "numpy array is not C contiguous; use ndarray.tolist() in default"NumpyNotNativeEndian
Numpy array is not in native endian format.
Message: "numpy array is not native-endianness"NumpyUnsupportedDatatype
The numpy array contains an unsupported data type.
Message: "unsupported datatype in numpy array"UnsupportedType(NonNull<pyo3_ffi::PyObject>)
The type of the object is not JSON serializable. Stores a non-null pointer to the Python object causing the error.
Message: "Type is not JSON serializable: " where<type_name>is dynamically retrieved from the Python object's type name at runtime.
Implementation Details
impl core::fmt::Display for SerializeError
This implementation enables converting `SerializeError` variants to human-readable error messages, facilitating meaningful error output.
Uses a
matchexpression to map each variant to a descriptive string.The
UnsupportedTypevariant dynamically retrieves the Python type name using unsafe code and FFI calls:It uses a macro
ob_type!(assumed imported elsewhere) to get the Python type pointer of the object.Uses
CStr::from_ptrto convert the raw C string pointer to a Rust string slice.Uses
to_string_lossy()to safely handle potential invalid UTF-8.
The
#[cold]attribute hints the compiler that this function is unlikely to be called frequently, optimizing for size.The #[cfg_attr(feature = "optimize", optimize(size))] attribute optionally instructs the compiler to optimize for binary size if the feature flag optimize is enabled.
Usage Example
use core::fmt;
fn serialize_value(value: &MyValue) -> Result<String, SerializeError> {
if !value.is_valid() {
return Err(SerializeError::InvalidStr);
}
// Serialization logic...
Ok("json_string".to_string())
}
fn main() {
match serialize_value(&my_value) {
Ok(json) => println!("Serialized JSON: {}", json),
Err(e) => println!("Serialization error: {}", e),
}
}
In this example, if serialization fails, the error message produced by `SerializeError`'s `Display` implementation will be printed.
Interaction with Other System Components
Serialization Module: This file is part of the serialization subsystem and used throughout serialization routines to represent and propagate errors.
Python FFI (pyo3_ffi): It interacts with Python objects at the FFI boundary, particularly for the
UnsupportedTypevariant, bridging Rust error handling with Python runtime details.Utility Modules: References constants such as
crate::util::INVALID_STRfor standardized error messages.Error Reporting & Debugging: Provides detailed error messages that can be surfaced to the user or developer for troubleshooting serialization issues.
Visual Diagram
classDiagram
class SerializeError {
<<enum>>
+DatetimeLibraryUnsupported
+DefaultRecursionLimit
+Integer53Bits
+Integer64Bits
+InvalidStr
+InvalidFragment
+KeyMustBeStr
+RecursionLimit
+TimeHasTzinfo
+DictIntegerKey64Bit
+DictKeyInvalidType
+NumpyMalformed
+NumpyNotCContiguous
+NumpyNotNativeEndian
+NumpyUnsupportedDatatype
+UnsupportedType(ptr: NonNull<PyObject>)
}
class Display {
+fmt(&self, f: &mut Formatter) -> Result
}
SerializeError ..> Display : implements
Summary
The [error.rs](/projects/287/67737) file encapsulates error conditions specific to JSON serialization, ensuring robust and clear error handling. It bridges Rust and Python types, especially when encountering unsupported Python objects during serialization. By implementing `Display` for `SerializeError`, it provides meaningful error messages essential for debugging and user feedback. This file is foundational to the serialization error management strategy in the larger system.