Skip to content

Commit c37a50a

Browse files
authored
Add example of more complex exceptions (#5014)
1 parent dcacb9b commit c37a50a

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

guide/src/exception.md

+47
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,50 @@ defines exceptions for several standard library modules.
136136
[`PyErr::from_value`]: {{#PYO3_DOCS_URL}}/pyo3/struct.PyErr.html#method.from_value
137137
[`PyAny::is_instance`]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.is_instance
138138
[`PyAny::is_instance_of`]: {{#PYO3_DOCS_URL}}/pyo3/types/trait.PyAnyMethods.html#tymethod.is_instance_of
139+
140+
## Creating more complex exceptions
141+
142+
If you need to create an exception with more complex behavior, you can also manually create a subclass of `PyException`:
143+
144+
```rust
145+
#![allow(dead_code)]
146+
# #[cfg(any(not(feature = "abi3")))] {
147+
use pyo3::prelude::*;
148+
use pyo3::types::IntoPyDict;
149+
use pyo3::exceptions::PyException;
150+
151+
#[pyclass(extends=PyException)]
152+
struct CustomError {
153+
#[pyo3(get)]
154+
url: String,
155+
156+
#[pyo3(get)]
157+
message: String,
158+
}
159+
160+
#[pymethods]
161+
impl CustomError {
162+
#[new]
163+
fn new(url: String, message: String) -> Self {
164+
Self { url, message }
165+
}
166+
}
167+
168+
# fn main() -> PyResult<()> {
169+
Python::with_gil(|py| {
170+
let ctx = [("CustomError", py.get_type::<CustomError>())].into_py_dict(py)?;
171+
pyo3::py_run!(
172+
py,
173+
*ctx,
174+
"assert str(CustomError) == \"<class 'builtins.CustomError'>\", repr(CustomError)"
175+
);
176+
pyo3::py_run!(py, *ctx, "assert CustomError('https://example.com', 'something went bad').args == ('https://example.com', 'something went bad')");
177+
pyo3::py_run!(py, *ctx, "assert CustomError('https://example.com', 'something went bad').url == 'https://example.com'");
178+
# Ok(())
179+
})
180+
# }
181+
# }
182+
183+
```
184+
185+
Note that this is not possible when the ``abi3`` feature is enabled, as that prevents subclassing ``PyException``.

0 commit comments

Comments
 (0)