base_error_handling/
base_error_handling.rs1use alpaca_base::{AlpacaError, ApiErrorCode, ApiErrorResponse, RateLimitInfo, ValidationError};
17
18fn main() -> Result<(), Box<dyn std::error::Error>> {
19 println!("=== Alpaca Error Handling Patterns ===\n");
20
21 println!("--- API Error Codes ---");
23 demonstrate_error_codes();
24
25 println!("\n--- Retryable Errors ---");
27 demonstrate_retryable_errors();
28
29 println!("\n--- Rate Limit Handling ---");
31 demonstrate_rate_limiting();
32
33 println!("\n--- Validation Errors ---");
35 demonstrate_validation_errors();
36
37 println!("\n--- Error Pattern Matching ---");
39 demonstrate_error_matching();
40
41 println!("\n=== Example Complete ===");
42 Ok(())
43}
44
45fn demonstrate_error_codes() {
46 let codes = [
48 (40010000, "Malformed Request"),
49 (40110000, "Invalid Credentials"),
50 (40310000, "Forbidden"),
51 (40410000, "Not Found"),
52 (42210000, "Unprocessable Entity"),
53 (42910000, "Rate Limit Exceeded"),
54 (50010000, "Internal Server Error"),
55 ];
56
57 for (code, description) in codes {
58 let error_code = ApiErrorCode::from_code(code);
59 println!(
60 " Code {}: {} (client_error={}, server_error={})",
61 code,
62 description,
63 error_code.is_client_error(),
64 error_code.is_server_error()
65 );
66 }
67}
68
69fn demonstrate_retryable_errors() {
70 let errors = [
71 ("Rate Limit", AlpacaError::rate_limit(60)),
72 (
73 "Network",
74 AlpacaError::Network("connection reset".to_string()),
75 ),
76 (
77 "Timeout",
78 AlpacaError::Timeout("request timed out".to_string()),
79 ),
80 ("Auth", AlpacaError::Auth("invalid key".to_string())),
81 ("Not Found", AlpacaError::api(404, "order not found")),
82 ("Server Error", AlpacaError::api(500, "internal error")),
83 ];
84
85 for (name, error) in errors {
86 let retry_info = if let Some(secs) = error.retry_after() {
87 format!(", retry after {} secs", secs)
88 } else {
89 String::new()
90 };
91 println!(
92 " {}: retryable={}{}",
93 name,
94 error.is_retryable(),
95 retry_info
96 );
97 }
98}
99
100fn demonstrate_rate_limiting() {
101 let info = RateLimitInfo::new()
103 .with_remaining(0)
104 .with_limit(200)
105 .with_retry_after(60);
106
107 println!(" Rate limit status:");
108 println!(" - Remaining: {:?}", info.remaining);
109 println!(" - Limit: {:?}", info.limit);
110 println!(" - Retry after: {:?} seconds", info.retry_after);
111 println!(" - Is limited: {}", info.is_limited());
112
113 let error = AlpacaError::rate_limit_with_info(info);
115 println!(" Error: {}", error);
116}
117
118fn demonstrate_validation_errors() {
119 let single_error = ValidationError::new("quantity", "must be greater than 0");
121 println!(" Single error: {}", single_error);
122
123 let errors = vec![
125 ValidationError::new("symbol", "is required"),
126 ValidationError::new("qty", "must be positive"),
127 ValidationError::new("side", "must be 'buy' or 'sell'"),
128 ];
129
130 let multi_error = AlpacaError::ValidationErrors(errors);
131 println!(" Multiple errors: {}", multi_error);
132}
133
134fn demonstrate_error_matching() {
135 let error = AlpacaError::api_with_details(
136 404,
137 "order not found",
138 ApiErrorCode::NotFound,
139 Some("req-12345".to_string()),
140 );
141
142 match &error {
144 AlpacaError::Api {
145 status,
146 message,
147 error_code,
148 request_id,
149 } => {
150 println!(" API Error detected:");
151 println!(" - Status: {}", status);
152 println!(" - Message: {}", message);
153 println!(" - Error code: {:?}", error_code);
154 println!(" - Request ID: {:?}", request_id);
155 }
156 AlpacaError::RateLimit {
157 retry_after_secs, ..
158 } => {
159 println!(" Rate limited, retry after {} seconds", retry_after_secs);
160 }
161 _ => {
162 println!(" Other error: {}", error);
163 }
164 }
165
166 println!("\n Helper methods:");
168 println!(" - status_code(): {:?}", error.status_code());
169 println!(" - request_id(): {:?}", error.request_id());
170 println!(" - is_retryable(): {}", error.is_retryable());
171
172 let response =
174 ApiErrorResponse::new(40410000, "resource not found").with_request_id("req-67890");
175 println!("\n Parsed API response:");
176 println!(" - Code: {}", response.code);
177 println!(" - Message: {}", response.message);
178 println!(" - Typed code: {:?}", response.error_code());
179}