Skip to main content

futu_core/
error.rs

1use thiserror::Error;
2
3/// Stable, redacted reason for a backend transport failure.
4///
5/// The reason is safe to inspect across crate boundaries. Diagnostic detail
6/// remains separately redacted by the transport owner before it reaches
7/// [`FutuError::TransportFailure`].
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum TransportFailureReason {
11    PeerEof,
12    CodecError,
13    Shutdown,
14    UnmatchedSerial,
15    ResponseTimeout,
16    SendError,
17}
18
19impl TransportFailureReason {
20    #[must_use]
21    pub const fn as_str(self) -> &'static str {
22        match self {
23            Self::PeerEof => "peer_eof",
24            Self::CodecError => "codec_error",
25            Self::Shutdown => "shutdown",
26            Self::UnmatchedSerial => "unmatched_serial",
27            Self::ResponseTimeout => "response_timeout",
28            Self::SendError => "send_error",
29        }
30    }
31}
32
33impl std::fmt::Display for TransportFailureReason {
34    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        formatter.write_str(self.as_str())
36    }
37}
38
39/// **Stable API** — FutuOpenD 统一错误类型。
40///
41/// 跨 10+ crate 共享的错误枚举,`#[non_exhaustive]` 表示下版可能新增变体
42/// (不算 breaking)。新增已有变体字段属于 breaking。
43#[derive(Debug, Error)]
44#[non_exhaustive]
45pub enum FutuError {
46    #[error("网络错误: {0}")]
47    Network(#[from] std::io::Error),
48
49    #[error("协议解析错误: {0}")]
50    Codec(String),
51
52    #[error("Protobuf 解码失败: {0}")]
53    Proto(#[from] prost::DecodeError),
54
55    #[error("服务端返回错误, ret_type={ret_type}, msg={msg}")]
56    ServerError { ret_type: i32, msg: String },
57
58    #[error("连接超时")]
59    Timeout,
60
61    /// A typed transport failure whose detail has already been redacted by
62    /// the backend connection diagnostics boundary.
63    #[error("传输失败 ({reason}): {detail}")]
64    TransportFailure {
65        reason: TransportFailureReason,
66        detail: String,
67    },
68
69    #[error("未初始化")]
70    NotInitialized,
71
72    #[error("已缓存的 SMS 验证仍在等待验证码输入")]
73    SmsVerificationCodeRequired,
74
75    #[error("加密错误: {0}")]
76    Encryption(String),
77
78    #[error("SHA1 校验失败")]
79    Sha1Mismatch,
80
81    #[error("无效的协议帧头")]
82    InvalidHeader,
83}
84
85/// **Stable API** — `Result<T, FutuError>` 的短别名。
86///
87/// 几乎所有 futu-* crate 的 pub fn signature 都用它。
88pub type Result<T> = std::result::Result<T, FutuError>;