kiteconnect_rs/models/
error.rs1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct KiteError {
6 pub status: String,
7 pub message: String,
8 pub data: Option<serde_json::Value>,
9 pub error_type: String,
10}
11
12impl fmt::Display for KiteError {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 write!(f, "Kite API Error: {} ({})", self.message, self.error_type)
15 }
16}
17
18impl std::error::Error for KiteError {}
19
20#[derive(Debug)]
21pub struct KiteConnectError {
22 pub kind: KiteConnectErrorKind,
23 pub backtrace: std::backtrace::Backtrace,
24}
25
26#[derive(Debug)]
27pub enum KiteConnectErrorKind {
28 ApiError(KiteError),
29 HttpError(reqwest::Error),
30 SerializationError(serde_json::Error),
31 InvalidHeader(reqwest::header::InvalidHeaderValue),
32 Other(String),
33}
34
35impl fmt::Display for KiteConnectError {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match &self.kind {
38 KiteConnectErrorKind::ApiError(e) => write!(f, "{}", e),
39 KiteConnectErrorKind::HttpError(e) => write!(f, "HTTP Error: {}", e),
40 KiteConnectErrorKind::SerializationError(e) => write!(f, "Serialization Error: {}", e),
41 KiteConnectErrorKind::InvalidHeader(e) => write!(f, "Invalid Header: {}", e),
42 KiteConnectErrorKind::Other(e) => write!(f, "Error: {}", e),
43 }
44 }
45}
46
47impl std::error::Error for KiteConnectError {
48 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
49 match &self.kind {
50 KiteConnectErrorKind::ApiError(e) => Some(e),
51 KiteConnectErrorKind::HttpError(e) => Some(e),
52 KiteConnectErrorKind::SerializationError(e) => Some(e),
53 KiteConnectErrorKind::InvalidHeader(e) => Some(e),
54 KiteConnectErrorKind::Other(_) => None,
55 }
56 }
57}
58
59impl KiteConnectError {
60 pub fn new(kind: KiteConnectErrorKind) -> Self {
62 KiteConnectError {
63 kind,
64 backtrace: std::backtrace::Backtrace::capture(),
65 }
66 }
67
68 pub fn other(msg: impl Into<String>) -> Self {
70 Self::new(KiteConnectErrorKind::Other(msg.into()))
71 }
72
73 pub fn backtrace(&self) -> &std::backtrace::Backtrace {
75 &self.backtrace
76 }
77
78 pub fn print_backtrace(&self) {
79 use std::backtrace::BacktraceStatus;
80
81 match self.backtrace.status() {
82 BacktraceStatus::Disabled | BacktraceStatus::Unsupported => {
83 eprintln!("Backtrace disabled (run with RUST_BACKTRACE=1)");
84 return;
85 }
86 BacktraceStatus::Captured => {}
87 _ => return,
88 }
89
90 let trace = self.backtrace.to_string();
91 let mut count = 0;
92
93 for line in trace.lines() {
94 if let Some(pos) = line.find(": ") {
96 let frame_num = line[..pos].trim();
97 let content = &line[pos + 2..];
98 eprintln!(" {} → {}", frame_num, content);
99 count += 1;
100 } else if line.trim().starts_with("at ") {
101 eprintln!(" {}", line.trim());
102 }
103 }
104
105 if count == 0 {
106 eprintln!(" (no frames to display)");
107 }
108 }
109}
110
111impl From<reqwest::Error> for KiteConnectError {
112 fn from(error: reqwest::Error) -> Self {
113 Self::new(KiteConnectErrorKind::HttpError(error))
114 }
115}
116
117impl From<serde_json::Error> for KiteConnectError {
118 fn from(error: serde_json::Error) -> Self {
119 Self::new(KiteConnectErrorKind::SerializationError(error))
120 }
121}
122
123impl From<reqwest::header::InvalidHeaderValue> for KiteConnectError {
124 fn from(error: reqwest::header::InvalidHeaderValue) -> Self {
125 Self::new(KiteConnectErrorKind::InvalidHeader(error))
126 }
127}
128
129impl From<KiteError> for KiteConnectError {
130 fn from(error: KiteError) -> Self {
131 Self::new(KiteConnectErrorKind::ApiError(error))
132 }
133}