Skip to content

Commit 9751f2d

Browse files
committed
Register custom exceptions for Python bindings
1 parent ae96685 commit 9751f2d

3 files changed

Lines changed: 94 additions & 4 deletions

File tree

cflib2/__init__.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@
2929
NoTocCache,
3030
InMemoryTocCache,
3131
FileTocCache,
32+
# Exceptions
33+
CrazyflieError,
34+
ProtocolVersionNotSupportedError,
35+
ProtocolError,
36+
ParamError,
37+
LogError,
38+
ConversionError,
39+
LinkError,
40+
DisconnectedError,
41+
VariableNotFoundError,
42+
SystemError,
43+
AppchannelPacketTooLargeError,
44+
InvalidArgumentError,
45+
TimeoutError,
46+
MemoryError,
47+
InvalidParameterError,
3248
)
3349

3450
__all__ = [
@@ -37,4 +53,20 @@
3753
"NoTocCache",
3854
"InMemoryTocCache",
3955
"FileTocCache",
56+
# Exceptions
57+
"CrazyflieError",
58+
"ProtocolVersionNotSupportedError",
59+
"ProtocolError",
60+
"ParamError",
61+
"LogError",
62+
"ConversionError",
63+
"LinkError",
64+
"DisconnectedError",
65+
"VariableNotFoundError",
66+
"SystemError",
67+
"AppchannelPacketTooLargeError",
68+
"InvalidArgumentError",
69+
"TimeoutError",
70+
"MemoryError",
71+
"InvalidParameterError",
4072
]

rust/src/error.rs

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// | / ,--' | / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
55
// +------` /_____/_/\__/\___/_/ \__,_/ /___/\___/
66
//
7-
// Copyright (C) 2025 Bitcraze AB
7+
// Copyright (C) 2026 Bitcraze AB
88
//
99
// This program is free software: you can redistribute it and/or modify
1010
// it under the terms of the GNU General Public License as published by
@@ -20,11 +20,68 @@
2020
// along with this program. If not, see <http://www.gnu.org/licenses/>.
2121

2222
//! Error conversion utilities for Python bindings
23+
//!
24+
//! Each exception maps 1:1 to a variant of `crazyflie_lib::Error`.
2325
24-
use pyo3::exceptions::PyRuntimeError;
25-
use pyo3::PyErr;
26+
use pyo3::create_exception;
27+
use pyo3::exceptions::PyException;
28+
use pyo3::prelude::*;
29+
30+
create_exception!(cflib2._rust, CrazyflieError, PyException, "Base exception for all Crazyflie errors.");
31+
create_exception!(cflib2._rust, ProtocolVersionNotSupportedError, CrazyflieError, "Protocol version not supported.");
32+
create_exception!(cflib2._rust, ProtocolError, CrazyflieError, "Unexpected protocol error.");
33+
create_exception!(cflib2._rust, ParamError, CrazyflieError, "Parameter subsystem error.");
34+
create_exception!(cflib2._rust, LogError, CrazyflieError, "Log subsystem error.");
35+
create_exception!(cflib2._rust, ConversionError, CrazyflieError, "Value conversion error.");
36+
create_exception!(cflib2._rust, LinkError, CrazyflieError, "Crazyflie link error.");
37+
create_exception!(cflib2._rust, DisconnectedError, CrazyflieError, "Crazyflie is disconnected.");
38+
create_exception!(cflib2._rust, VariableNotFoundError, CrazyflieError, "Variable not found in TOC.");
39+
create_exception!(cflib2._rust, SystemError, CrazyflieError, "Async executor error.");
40+
create_exception!(cflib2._rust, AppchannelPacketTooLargeError, CrazyflieError, "App channel packet exceeds MTU.");
41+
create_exception!(cflib2._rust, InvalidArgumentError, CrazyflieError, "Invalid argument.");
42+
create_exception!(cflib2._rust, TimeoutError, CrazyflieError, "Operation timed out.");
43+
create_exception!(cflib2._rust, MemoryError, CrazyflieError, "Memory subsystem error.");
44+
create_exception!(cflib2._rust, InvalidParameterError, CrazyflieError, "Invalid parameter.");
45+
46+
/// Register all custom exception types with the Python module
47+
pub fn register_exceptions(m: &Bound<'_, PyModule>) -> PyResult<()> {
48+
let py = m.py();
49+
m.add("CrazyflieError", py.get_type::<CrazyflieError>())?;
50+
m.add("ProtocolVersionNotSupportedError", py.get_type::<ProtocolVersionNotSupportedError>())?;
51+
m.add("ProtocolError", py.get_type::<ProtocolError>())?;
52+
m.add("ParamError", py.get_type::<ParamError>())?;
53+
m.add("LogError", py.get_type::<LogError>())?;
54+
m.add("ConversionError", py.get_type::<ConversionError>())?;
55+
m.add("LinkError", py.get_type::<LinkError>())?;
56+
m.add("DisconnectedError", py.get_type::<DisconnectedError>())?;
57+
m.add("VariableNotFoundError", py.get_type::<VariableNotFoundError>())?;
58+
m.add("SystemError", py.get_type::<SystemError>())?;
59+
m.add("AppchannelPacketTooLargeError", py.get_type::<AppchannelPacketTooLargeError>())?;
60+
m.add("InvalidArgumentError", py.get_type::<InvalidArgumentError>())?;
61+
m.add("TimeoutError", py.get_type::<TimeoutError>())?;
62+
m.add("MemoryError", py.get_type::<MemoryError>())?;
63+
m.add("InvalidParameterError", py.get_type::<InvalidParameterError>())?;
64+
Ok(())
65+
}
2666

2767
/// Convert Rust crazyflie_lib errors to Python exceptions
2868
pub fn to_pyerr(err: crazyflie_lib::Error) -> PyErr {
29-
PyRuntimeError::new_err(format!("Crazyflie error: {:?}", err))
69+
use crazyflie_lib::Error::*;
70+
let msg = err.to_string();
71+
match err {
72+
ProtocolVersionNotSupported { .. } => ProtocolVersionNotSupportedError::new_err(msg),
73+
ProtocolError(_) => self::ProtocolError::new_err(msg),
74+
ParamError(_) => self::ParamError::new_err(msg),
75+
LogError(_) => self::LogError::new_err(msg),
76+
ConversionError(_) => self::ConversionError::new_err(msg),
77+
LinkError(_) => self::LinkError::new_err(msg),
78+
Disconnected => DisconnectedError::new_err(msg),
79+
VariableNotFound => VariableNotFoundError::new_err(msg),
80+
SystemError(_) => self::SystemError::new_err(msg),
81+
AppchannelPacketTooLarge => AppchannelPacketTooLargeError::new_err(msg),
82+
InvalidArgument(_) => InvalidArgumentError::new_err(msg),
83+
Timeout => self::TimeoutError::new_err(msg),
84+
MemoryError(_) => self::MemoryError::new_err(msg),
85+
InvalidParameter(_) => InvalidParameterError::new_err(msg),
86+
}
3087
}

rust/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ fn _rust(m: &Bound<'_, PyModule>) -> PyResult<()> {
7272
m.add_class::<NoTocCache>()?;
7373
m.add_class::<InMemoryTocCache>()?;
7474
m.add_class::<FileTocCache>()?;
75+
error::register_exceptions(m)?;
7576
Ok(())
7677
}
7778

0 commit comments

Comments
 (0)