Skip to main content

tauri_plugin_py_runtime/
error.rs

1//! 插件统一的错误类型与错误码。
2//!
3//! 职责:定义在 Rust、Python 与前端之间共用的错误形状 `{ code, message, data? }`。
4//! [`Error`] 会被序列化后原样返回给前端(前端包装为 `PyRuntimeError`),Python 端
5//! `error` 帧中的 `code` / `message` / `data` 也会直接映射为 [`Error`]。
6//!
7//! 不变量:`code` 是稳定的机器可读字符串。插件自身只产生 [`codes`] 中列出的错误码,
8//! Python 通过 `TauriError` 抛出的自定义错误码会原样透传。
9
10use serde::Serialize;
11use serde_json::Value;
12
13/// 插件内置的错误码常量,与 README 中的错误码表一一对应。
14pub mod codes {
15  /// Python 端没有注册该名称的命令。
16  pub const COMMAND_NOT_FOUND: &str = "command_not_found";
17  /// 参数非法:缺少参数、pydantic 校验失败、请求头格式错误或客户端调用 id 重复等。
18  pub const INVALID_ARGS: &str = "invalid_args";
19  /// Python 中未处理的异常,或插件内部错误(I/O 失败、载荷格式不一致等)。
20  pub const INTERNAL: &str = "internal";
21  /// 调用被前端主动取消。
22  pub const CANCELLED: &str = "cancelled";
23  /// 调用超过了超时时间。
24  pub const TIMEOUT: &str = "timeout";
25  /// Python 运行时不可用:启动失败、握手失败或超时、已停止,或写通道已关闭。
26  pub const RUNTIME_UNAVAILABLE: &str = "runtime_unavailable";
27  /// 调用进行中时 Python 进程意外退出。
28  pub const RUNTIME_EXITED: &str = "runtime_exited";
29  /// Python SDK 使用的协议版本与本插件不一致,或首帧无法解码。
30  pub const PROTOCOL_MISMATCH: &str = "protocol_mismatch";
31  /// 帧大小超过上限(默认 64 MiB,见 [`crate::bridge::DEFAULT_MAX_FRAME_SIZE`])。
32  pub const FRAME_TOO_LARGE: &str = "frame_too_large";
33}
34
35/// 结构化错误,序列化为 `{ code, message, data? }` 返回给前端。
36#[derive(Debug, Clone, PartialEq, Serialize, thiserror::Error)]
37#[error("{code}: {message}")]
38pub struct Error {
39  /// 机器可读的错误码,通常取自 [`codes`],也可能是 Python 自定义的错误码。
40  pub code: String,
41  /// 面向开发者的错误描述。
42  pub message: String,
43  /// 可选的附加数据(任意 JSON),为 `None` 时序列化结果中不包含该字段。
44  #[serde(skip_serializing_if = "Option::is_none")]
45  pub data: Option<Value>,
46}
47
48impl Error {
49  /// 以错误码和描述构造不带 `data` 的错误。
50  pub fn new(code: impl Into<String>, message: impl Into<String>) -> Self {
51    Self { code: code.into(), message: message.into(), data: None }
52  }
53
54  /// 附加 `data` 字段并返回自身,便于链式构造。
55  pub fn with_data(mut self, data: Value) -> Self {
56    self.data = Some(data);
57    self
58  }
59}
60
61impl From<std::io::Error> for Error {
62  fn from(e: std::io::Error) -> Self {
63    Self::new(codes::INTERNAL, e.to_string())
64  }
65}
66
67impl From<tauri::Error> for Error {
68  fn from(e: tauri::Error) -> Self {
69    Self::new(codes::INTERNAL, e.to_string())
70  }
71}
72
73/// 以 [`Error`] 为错误类型的 `Result` 别名。
74pub type Result<T> = std::result::Result<T, Error>;