1use thiserror::Error;
8
9use uni_plugin::PluginError;
10
11#[derive(Debug, Error)]
13#[non_exhaustive]
14pub enum PyPluginError {
15 #[error("python callable signature unrecognized: {0}")]
19 SignatureUnrecognized(String),
20
21 #[error("python exception in `{qname}`: {message}\n{traceback}")]
24 PythonException {
25 qname: String,
27 message: String,
29 traceback: String,
31 },
32
33 #[error("python plugin manifest invalid: {0}")]
36 ManifestInvalid(String),
37
38 #[error("python plugin registrar rejected: {0}")]
41 RegistrarRejected(String),
42
43 #[error("arrow <-> pyarrow conversion failure: {0}")]
47 ArrowConversion(String),
48
49 #[error("uni-plugin-pyo3 internal error: {0}")]
51 Internal(String),
52}
53
54#[cfg(feature = "pyo3")]
55impl From<pyo3::PyErr> for PyPluginError {
56 fn from(err: pyo3::PyErr) -> Self {
57 use pyo3::types::{PyAnyMethods, PyTracebackMethods};
58
59 pyo3::Python::attach(|py| {
62 let traceback = err
63 .traceback(py)
64 .and_then(|tb| tb.format().ok())
65 .unwrap_or_default();
66 let value = err.value(py);
67 let message = value
68 .repr()
69 .map(|r| r.to_string())
70 .unwrap_or_else(|_| err.to_string());
71 PyPluginError::PythonException {
72 qname: String::from("<unknown>"),
73 message,
74 traceback,
75 }
76 })
77 }
78}
79
80#[cfg(feature = "pyo3")]
81impl PyPluginError {
82 #[must_use]
85 pub fn with_qname(self, qname: impl Into<String>) -> Self {
86 match self {
87 PyPluginError::PythonException {
88 qname: _,
89 message,
90 traceback,
91 } => PyPluginError::PythonException {
92 qname: qname.into(),
93 message,
94 traceback,
95 },
96 other => other,
97 }
98 }
99}
100
101impl From<PluginError> for PyPluginError {
102 fn from(err: PluginError) -> Self {
103 match err {
104 PluginError::DuplicateRegistration(q) => {
105 PyPluginError::RegistrarRejected(format!("duplicate registration: {q}"))
106 }
107 PluginError::CapabilityRequired(c) => {
108 PyPluginError::RegistrarRejected(format!("registrar caps missing: {c:?}"))
109 }
110 other => PyPluginError::Internal(format!("registrar: {other}")),
111 }
112 }
113}