diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | mullvad-problem-report/src/lib.rs | 32 |
2 files changed, 28 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 946586d763..7f70ad51bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Line wrap the file at 100 chars. Th - Read account token from standard input unless given as an argument in CLI. - Make WireGuard automatic key rotation interval mandatory and between 1 and 7 days. - Show default, minimum, and maximum key rotation intervals in CLI. +- Attempt to send problem reports using other endpoints if using the primary one fails. #### Android - WireGuard key is now rotated sooner: every four days instead of seven. diff --git a/mullvad-problem-report/src/lib.rs b/mullvad-problem-report/src/lib.rs index b4faa5acf3..bd77f3012a 100644 --- a/mullvad-problem-report/src/lib.rs +++ b/mullvad-problem-report/src/lib.rs @@ -10,6 +10,7 @@ use std::{ fs::{self, File}, io::{self, BufWriter, Read, Seek, SeekFrom, Write}, path::{Path, PathBuf}, + time::Duration, }; use talpid_types::ErrorExt; @@ -33,6 +34,9 @@ const LINE_SEPARATOR: &str = "\n"; #[cfg(windows)] const LINE_SEPARATOR: &str = "\r\n"; +const MAX_SEND_ATTEMPTS: usize = 3; +const RETRY_INTERVAL: Duration = Duration::from_millis(500); + /// Custom macro to write a line to an output formatter that uses platform-specific newline /// character sequences. macro_rules! write_line { @@ -64,8 +68,8 @@ pub enum Error { #[error(display = "Unable to create REST client")] CreateRpcClientError(#[error(source)] mullvad_rpc::Error), - #[error(display = "Error during RPC call")] - SendRpcError(#[error(source)] mullvad_rpc::rest::Error), + #[error(display = "Failed to send problem report")] + SendProblemReportError, #[error(display = "Unable to spawn Tokio runtime")] CreateRuntime(#[error(source)] io::Error), @@ -289,9 +293,27 @@ pub fn send_problem_report( .map_err(Error::CreateRpcClientError)?; let rpc_client = mullvad_rpc::ProblemReportProxy::new(rpc_manager.mullvad_rest_handle()); - runtime - .block_on(rpc_client.problem_report(user_email, user_message, &report_content, &metadata)) - .map_err(Error::SendRpcError) + runtime.block_on(async move { + for _attempt in 0..MAX_SEND_ATTEMPTS { + match rpc_client + .problem_report(user_email, user_message, &report_content, &metadata) + .await + { + Ok(()) => { + println!("Problem report sent."); + return Ok(()); + } + Err(error) => { + eprintln!( + "{}", + error.display_chain_with_msg("Failed to send problem report") + ) + } + } + tokio::time::delay_for(RETRY_INTERVAL).await; + } + Err(Error::SendProblemReportError) + }) } fn write_problem_report(path: &Path, problem_report: &ProblemReport) -> io::Result<()> { |
