4 files changed
+68
-4
crates/cli/src/main.rs
+20
-1
@@ -12,7 +12,7 @@ use smbcloud_cli::{
12
cli::{Cli, Commands},
13
deploy::process_deploy,
14
};
15
-use smbcloud_networking::environment::Environment;
15
+use smbcloud_networking::{check_internet_connection, environment::Environment};
16
use std::{
17
fs::{create_dir_all, OpenOptions},
18
path::PathBuf,
@@ -111,6 +111,25 @@ async fn run() -> Result<CommandResult> {
111
setup_logging(cli.environment, None)?;
112
}
113
114
+ // Check if the command requires internet connection
115
+ let needs_internet = match &cli.command {
116
+ Some(Commands::Me {})
117
+ | Some(Commands::Deploy {})
118
+ | Some(Commands::Login {})
119
+ | Some(Commands::Logout {})
120
+ | Some(Commands::Account { .. })
121
+ | Some(Commands::Project { .. })
122
+ | None => true,
123
+ Some(Commands::Init {}) => true,
124
+ };
125
+
126
+ // Check internet connectivity for commands that need it
127
+ if needs_internet && !check_internet_connection().await {
128
+ return Err(anyhow!(
129
+ "No internet connection. Please check your network settings and try again."
130
+ ));
131
+ }
132
+
133
match cli.command {
134
Some(Commands::Me {}) => process_me(cli.environment).await,
135
Some(Commands::Init {}) => process_project_init(cli.environment).await,
crates/smbcloud-model/src/error_codes.rs
+4
-2
@@ -29,7 +29,7 @@ pub enum ErrorCode {
29
Unknown = 0,
30
#[error("Parse error.")]
31
ParseError = 1,
32
- #[error("Network error.")]
32
+ #[error("Network connectivity error.")]
33
NetworkError = 2,
34
#[error("Input error")]
35
InputError = 3,
@@ -74,7 +74,9 @@ impl ErrorCode {
74
ErrorCode::Unknown => "Unknown error.",
75
ErrorCode::ProjectNotFound => "Project not found.",
76
ErrorCode::ParseError => "Parse error.",
77
- ErrorCode::NetworkError => "Network error.",
77
+ ErrorCode::NetworkError => {
78
+ "Network error. Please check your internet connection and try again."
79
+ }
80
ErrorCode::Unauthorized => "Unauthorized access.",
81
ErrorCode::InputError => "Input error.",
82
ErrorCode::MissingConfig => "Missing config.",
crates/smbcloud-networking/src/lib.rs
+2
@@ -2,6 +2,8 @@ pub mod constants;
2
pub mod environment;
3
pub mod network;
4
5
+pub use network::check_internet_connection;
6
+
7
use anyhow::{anyhow, Result};
8
use constants::{SMB_CLIENT_ID, SMB_CLIENT_SECRET};
9
use environment::Environment;
crates/smbcloud-networking/src/network.rs
+42
-1
@@ -1,12 +1,43 @@
1
-use log::error;
1
+use log::{debug, error};
2
use reqwest::{RequestBuilder, Response};
3
use serde::de::DeserializeOwned;
4
use smbcloud_model::error_codes::{ErrorCode, ErrorResponse};
5
+use std::time::Duration;
6
#[cfg(debug_assertions)]
7
const LOG_RESPONSE_BODY: bool = false; // You know what to do here.
8
#[cfg(not(debug_assertions))]
9
const LOG_RESPONSE_BODY: bool = false;
10
11
+/// Check if there is an active internet connection
12
+///
13
+/// This function attempts to connect to a reliable server (dns.google)
14
+/// with a short timeout. Returns true if the connection was successful.
15
+pub async fn check_internet_connection() -> bool {
16
+ debug!("Checking internet connection");
17
+ let client = reqwest::Client::builder()
18
+ .timeout(Duration::from_secs(5))
19
+ .build();
20
+
21
+ if let Err(e) = client {
22
+ error!("Failed to create client for connectivity check: {:?}", e);
23
+ return false;
24
+ }
25
+
26
+ match client.unwrap().get("https://dns.google").send().await {
27
+ Ok(response) => {
28
+ debug!(
29
+ "Internet connection check successful: {}",
30
+ response.status()
31
+ );
32
+ response.status().is_success()
33
+ }
34
+ Err(e) => {
35
+ error!("Internet connection check failed: {:?}", e);
36
+ false
37
+ }
38
+ }
39
+}
40
+
41
pub async fn parse_error_response<T: DeserializeOwned>(
42
response: Response,
43
) -> Result<T, ErrorResponse> {
@@ -44,6 +75,16 @@ pub async fn parse_error_response<T: DeserializeOwned>(
75
}
76
77
pub async fn request<R: DeserializeOwned>(builder: RequestBuilder) -> Result<R, ErrorResponse> {
78
+ // Check internet connection before making the request
79
+ if !check_internet_connection().await {
80
+ error!("No internet connection available");
81
+ return Err(ErrorResponse::Error {
82
+ error_code: ErrorCode::NetworkError,
83
+ message: "No internet connection. Please check your network settings and try again."
84
+ .to_string(),
85
+ });
86
+ }
87
+
88
let response = builder.send().await;
89
let response = match response {
90
Ok(response) => response,