athena_cli/
aws.rs

1use anyhow::Result;
2
3/// Builds and returns an AWS SDK configuration based on the following priority:
4/// 1. Specified AWS profile (if provided)
5/// 2. AWS environment variables (if available)
6/// 3. Interactive SSO login (if user confirms)
7///
8/// This function can be reused to create any AWS service client.
9pub async fn build_aws_config(
10    profile: Option<String>,
11    region: String,
12) -> Result<aws_config::SdkConfig> {
13    let mut builder = aws_config::defaults(aws_config::BehaviorVersion::latest());
14
15    if let Some(profile_name) = profile {
16        builder = builder.profile_name(profile_name);
17    }
18
19    builder = builder.region(aws_config::Region::new(region));
20
21    Ok(builder.load().await)
22}
23
24/// Helper function to handle common AWS authentication errors with helpful messages
25pub fn handle_aws_auth_error(err: anyhow::Error, profile: Option<String>) -> anyhow::Error {
26    let err_string = format!("{:?}", err);
27
28    if err_string.contains("ForbiddenException")
29        || err_string.contains("AccessDenied")
30        || err_string.contains("ExpiredToken")
31        || err_string.contains("credentials")
32        || err_string.contains("auth")
33    {
34        println!("AWS Authentication Error: Your credentials may be expired or insufficient.");
35
36        if let Some(profile_name) = profile {
37            println!("\nPlease run: aws sso login --profile {}", profile_name);
38        } else {
39            println!("\nPlease set valid AWS credentials or configure a profile.");
40        }
41
42        anyhow::anyhow!("Authentication failure")
43    } else {
44        err
45    }
46}