use open_lark::core::{error_helper::ErrorHelper, trait_system::ExecutableBuilder};
use open_lark::prelude::*;
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenvy::dotenv().ok();
println!("🛡️ 飞书SDK增强错误处理示例");
println!("{}", "=".repeat(60));
demonstrate_authentication_errors().await;
demonstrate_api_error_handling().await;
demonstrate_retry_strategies().await;
demonstrate_response_analysis().await;
Ok(())
}
async fn demonstrate_authentication_errors() {
println!("\n📋 场景1: 认证错误处理");
println!("{}", "-".repeat(40));
let client = LarkClient::builder("invalid_app_id", "invalid_app_secret")
.with_enable_token_cache(false)
.build();
let message_body = open_lark::service::im::v1::message::CreateMessageRequestBody::builder()
.receive_id("test_user")
.msg_type("text")
.content(json!({"text": "测试消息"}).to_string())
.build();
match open_lark::service::im::v1::message::CreateMessageRequest::builder()
.receive_id_type("open_id")
.request_body(message_body)
.execute(&client.im.v1.message)
.await
{
Ok(_) => println!("✅ 意外成功"),
Err(error) => {
println!("❌ 捕获到错误(预期)");
handle_error_with_enhanced_features(&error);
}
}
}
async fn demonstrate_api_error_handling() {
println!("\n📋 场景2: API错误分析");
println!("{}", "-".repeat(40));
let api_errors = vec![
(403, "权限不足", "模拟权限错误"),
(429, "请求频率过高", "模拟限流错误"),
(500, "内部服务器错误", "模拟服务器错误"),
(404, "资源不存在", "模拟资源不存在错误"),
];
for (code, message, description) in api_errors {
println!("\n🔍 {description}: ");
let error = LarkAPIError::api_error(code, message, Some("req_123456".to_string()));
let advice = ErrorHelper::handle_error(&error);
println!(" 分类: {:?}", advice.category);
println!(
" 可恢复: {}",
if advice.is_recoverable { "是" } else { "否" }
);
println!(
" 可重试: {}",
if advice.is_retryable { "是" } else { "否" }
);
if let Some(delay) = advice.retry_delay {
println!(" 建议延迟: {delay}秒");
}
if !advice.actions.is_empty() {
println!(" 建议操作:");
for action in &advice.actions {
println!(" - {action}");
}
}
}
}
async fn demonstrate_retry_strategies() {
println!("\n📋 场景3: 智能重试策略");
println!("{}", "-".repeat(40));
let retryable_errors = vec![
LarkAPIError::api_error(429, "Too Many Requests", None),
LarkAPIError::api_error(500, "Internal Server Error", None),
LarkAPIError::api_error(503, "Service Unavailable", None),
];
for error in retryable_errors {
println!("\n🔄 错误: {}", ErrorHelper::format_user_error(&error));
if let Some(strategy) = ErrorHelper::create_retry_strategy(&error) {
println!(" 重试策略:");
println!(" - 最大重试次数: {}", strategy.max_attempts);
println!(" - 基础延迟: {:?}", strategy.base_delay);
println!(
" - 指数退避: {}",
if strategy.use_exponential_backoff {
"启用"
} else {
"禁用"
}
);
println!(" - 重试延迟序列:");
for attempt in 0..strategy.max_attempts {
let delay = strategy.calculate_delay(attempt);
println!(" 第{}次重试: {:?}", attempt + 1, delay);
}
} else {
println!(" 此错误不建议重试");
}
}
}
async fn demonstrate_response_analysis() {
println!("\n📋 场景4: 响应分析和错误诊断");
println!("{}", "-".repeat(40));
let mock_responses = vec![
(0, "success", "成功响应"),
(403, "Forbidden", "权限不足响应"),
(99991671, "access_token_invalid", "访问令牌无效响应"),
];
for (code, message, description) in mock_responses {
println!("\n🔍 分析{description}: ");
let raw_response = open_lark::core::api_resp::RawResponse {
code,
msg: message.to_string(),
err: None,
};
let response = open_lark::core::api_resp::BaseResponse {
raw_response,
data: Some("mock_data".to_string()),
};
if response.success() {
println!(" ✅ 请求成功");
} else {
println!(" ❌ 请求失败");
if let Some(error_code) = response.error_code() {
println!(" 错误码: {error_code} ({code})");
println!(" 详细描述: {}", error_code.detailed_description());
println!(" 错误分类: {:?}", error_code.category());
}
if let Some(friendly_error) = response.user_friendly_error() {
println!(" 用户友好错误: {friendly_error}");
}
let solutions = response.error_solutions();
if !solutions.is_empty() {
println!(" 解决方案:");
for solution in solutions {
println!(" - {solution}");
}
}
if response.is_retryable() {
if let Some(delay) = response.suggested_retry_delay() {
println!(" ⏱️ 建议重试延迟: {delay}秒");
}
}
let help_links = response.help_links();
if !help_links.is_empty() {
println!(" 📚 相关文档:");
for (name, url) in help_links {
println!(" {name}: {url}");
}
}
}
}
}
fn handle_error_with_enhanced_features(error: &LarkAPIError) {
println!("\n🔧 增强错误处理分析:");
let user_message = ErrorHelper::format_user_error(error);
println!(" 用户消息: {user_message}");
let context = ErrorHelper::create_error_context(error);
println!(" 错误分类: {:?}", context.category);
println!(
" 可恢复性: {}",
if context.is_recoverable {
"可恢复"
} else {
"需人工干预"
}
);
if !context.suggested_actions.is_empty() {
println!(" 建议操作:");
for (i, action) in context.suggested_actions.iter().enumerate() {
println!(" {}. {}", i + 1, action);
}
}
if let Some(strategy) = &context.retry_strategy {
println!(
" 重试策略: 最多{}次,基础延迟{:?}",
strategy.max_attempts, strategy.base_delay
);
}
if let Some(help_url) = &context.help_url {
println!(" 帮助文档: {help_url}");
}
println!("\n📊 详细错误信息:");
context.print_details();
}
#[allow(dead_code)]
async fn enhanced_api_call_example() -> Result<(), Box<dyn std::error::Error>> {
let app_id = std::env::var("APP_ID").unwrap_or_else(|_| "demo_app_id".to_string());
let app_secret = std::env::var("APP_SECRET").unwrap_or_else(|_| "demo_app_secret".to_string());
let client = LarkClient::builder(&app_id, &app_secret)
.with_enable_token_cache(true)
.build();
let message_body = open_lark::service::im::v1::message::CreateMessageRequestBody::builder()
.receive_id("demo_user")
.msg_type("text")
.content(json!({"text": "测试消息"}).to_string())
.build();
match open_lark::service::im::v1::message::CreateMessageRequest::builder()
.receive_id_type("open_id")
.request_body(message_body)
.execute(&client.im.v1.message)
.await
{
Ok(response) => {
println!("✅ 消息发送成功: {}", response.message_id);
}
Err(error) => {
println!("❌ API调用失败");
let context = ErrorHelper::create_error_context(&error);
if context.is_retryable {
if let Some(strategy) = &context.retry_strategy {
println!("🔄 错误可重试,建议延迟 {:?} 后重试", strategy.base_delay);
println!("⏰ 建议延迟 {:?} 后重试", strategy.base_delay);
}
} else {
println!("🚫 错误不可重试,需要人工干预");
context.print_details();
}
return Err(error.into());
}
}
Ok(())
}