Error Handling and Exceptions
Overview
The **Error Handling and Exceptions** module defines custom exception types to represent errors encountered during JSON encoding and decoding operations. These exceptions provide clear, specific error signaling for Python users of the library, improving error diagnosis and control flow when serialization or deserialization fails.
This module exists to:
Differentiate JSON-specific errors from generic Python exceptions.
Provide exceptions consistent with Python’s standard JSON library interface for ease of use.
Encapsulate error information originating from the Rust core or underlying C parser in an idiomatic Python form.
Allow client code to catch, handle, or propagate JSON errors precisely.
Core Exception Types
Two primary exception classes are exposed in the Python API:
1. JSONDecodeError
Inherits from Python's built-in
json.JSONDecodeError.Raised when the JSON deserialization process fails due to invalid syntax, malformed input, or structural errors in the input JSON string or bytes.
Mirrors the interface of
json.JSONDecodeErrorto maintain compatibility with existing Python JSON error handling patterns.Enables users to catch JSON parsing errors specifically when calling the loads() function.
2. JSONEncodeError
Inherits from Python’s built-in
TypeError.Raised when serialization to JSON fails, for example due to unsupported Python object types that cannot be converted to JSON by default.
Supports signaling fallback or custom serialization failures encountered in the
dumps()function.Allows differentiation from other type-related errors by indicating JSON encoding context.
How This Module Works
These exceptions are defined in the Python API layer (`pysrc/orjson/__init__.pyi`) as subclasses of standard Python exceptions, allowing seamless integration with Python’s error handling mechanisms.
The core Rust and C components propagate errors up to the Python bindings, where they are wrapped into these specific exception types. This wrapping ensures:
Consistent error messages.
Preservation of error metadata like error position for decoding failures.
Clear API documentation and typing for users.
For example, the [loads()](/projects/287/67747) function raises `JSONDecodeError` upon encountering invalid JSON input, enabling users to catch parsing errors gracefully:
try:
obj = orjson.loads(b'invalid json')
except orjson.JSONDecodeError as e:
print("JSON parsing failed:", e)
Similarly, `dumps()` raises `JSONEncodeError` when serialization fails due to unsupported Python data types:
try:
json_bytes = orjson.dumps(custom_object)
except orjson.JSONEncodeError as e:
print("JSON serialization failed:", e)
Interaction with Other Modules
The Error Handling and Exceptions module is tightly integrated with the serialization (
src/serialize) and deserialization (src/deserialize) modules within Rust core.When the Rust core detects an error during parsing or serialization, it returns an error result that the FFI layer (
src/ffi) translates into Python exceptions.These exceptions are then exposed by the Python API layer (
pysrc/orjson/__init__.py).This design cleanly separates error detection (Rust core), error translation (FFI), and error exposure (Python API), maintaining clarity and modularity.
Design Patterns and Concepts
Exception Wrapping Pattern: Rust errors and C-level parsing errors are caught and converted into Python exceptions with appropriate inheritance, preserving the semantic meaning of errors.
Compatibility Pattern: By inheriting from Python’s
json.JSONDecodeErrorandTypeError, the exceptions maintain compatibility with existing Python JSON error handling code, lowering adoption friction.Clear API Contract: The typing stub file (
pysrc/orjson/__init__.pyi) explicitly declares these exception classes, providing type checking and IDE hints for developers.Minimal Surface Area: Only two main exception classes are exposed, avoiding complicated exception hierarchies and simplifying error handling for users.
Code Reference
From the typing stub file `pysrc/orjson/__init__.pyi`:
import json
class JSONDecodeError(json.JSONDecodeError): ...
class JSONEncodeError(TypeError): ...
This shows the inheritance relationships and that these exceptions are part of the public API.
Visualization: Error Propagation Flow
sequenceDiagram
participant PyUser as Python User Code
participant PyAPI as orjson Python API
participant RustFFI as Rust FFI Layer
participant RustCore as Rust Serialization/Deserialization Core
participant YYJSON as yyjson C Parsing Library
PyUser->>PyAPI: Call loads(json_bytes)
PyAPI->>RustFFI: Invoke Rust deserializer
RustFFI->>RustCore: Deserialize JSON bytes
RustCore->>YYJSON: Parse JSON
YYJSON-->>RustCore: Return parse error (if any)
RustCore-->>RustFFI: Return error result
RustFFI-->>PyAPI: Raise JSONDecodeError
PyAPI-->>PyUser: Propagate JSONDecodeError exception
alt Serialization Error
PyUser->>PyAPI: Call dumps(python_obj)
PyAPI->>RustFFI: Invoke Rust serializer
RustFFI->>RustCore: Serialize Python object
RustCore-->>RustFFI: Return error for unsupported type
RustFFI-->>PyAPI: Raise JSONEncodeError
PyAPI-->>PyUser: Propagate JSONEncodeError exception
end
This sequence diagram illustrates the flow of calls from Python user code into Rust components and the propagation of JSON-related errors back as Python exceptions.
This documentation page details the purpose, design, usage, and integration of the custom error handling and exception types that provide robust, clear, and Pythonic error reporting for JSON encoding and decoding operations within the project.