Skip to content

Commit 7ee7cad

Browse files
fix: Don't error if invalid value supplied for max retries
Currently, if an invalid value is supplied for the maximum retry count, the CLI will panic, if a command which reads this value is called. Since we can always fall back to a reasonable default, we should probably warn instead of errroring at all when an invalid value is supplied. This change is done in preparation for #2209, since that change will add retries to all endpoints, increasing the chance of a user encountering a panic if this behavior is left unfixed.
1 parent b68484d commit 7ee7cad

File tree

3 files changed

+51
-21
lines changed

3 files changed

+51
-21
lines changed

src/api/errors/api_error.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ pub(in crate::api) enum ApiErrorKind {
4444
"DSN missing. Please set the `SENTRY_DSN` environment variable to your project's DSN."
4545
)]
4646
DsnMissing,
47-
#[error("Error preparing request")]
48-
ErrorPreparingRequest,
4947
}
5048

5149
impl fmt::Display for ApiError {

src/api/mod.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ impl Api {
396396
.request(Method::Post, url, None)?
397397
.with_form_data(form)?
398398
.with_retry(
399-
self.config.get_max_retry_count().unwrap(),
399+
self.config.get_max_retry_count(),
400400
&[
401401
http::HTTP_STATUS_502_BAD_GATEWAY,
402402
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
@@ -968,7 +968,7 @@ impl<'a> AuthenticatedApi<'a> {
968968
self.request(Method::Post, &url)?
969969
.with_json_body(request)?
970970
.with_retry(
971-
self.api.config.get_max_retry_count().unwrap(),
971+
self.api.config.get_max_retry_count(),
972972
&[
973973
http::HTTP_STATUS_502_BAD_GATEWAY,
974974
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
@@ -1001,7 +1001,7 @@ impl<'a> AuthenticatedApi<'a> {
10011001
dist: None,
10021002
})?
10031003
.with_retry(
1004-
self.api.config.get_max_retry_count().unwrap(),
1004+
self.api.config.get_max_retry_count(),
10051005
&[
10061006
http::HTTP_STATUS_502_BAD_GATEWAY,
10071007
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
@@ -1032,7 +1032,7 @@ impl<'a> AuthenticatedApi<'a> {
10321032
dist,
10331033
})?
10341034
.with_retry(
1035-
self.api.config.get_max_retry_count().unwrap(),
1035+
self.api.config.get_max_retry_count(),
10361036
&[
10371037
http::HTTP_STATUS_502_BAD_GATEWAY,
10381038
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
@@ -1408,12 +1408,7 @@ impl RegionSpecificApi<'_> {
14081408
self.request(Method::Post, &path)?
14091409
.with_form_data(form)?
14101410
.with_retry(
1411-
self.api.api.config.get_max_retry_count().map_err(|e| {
1412-
ApiError::with_source(
1413-
ApiErrorKind::ErrorPreparingRequest,
1414-
e.context("Could not parse retry count"),
1415-
)
1416-
})?,
1411+
self.api.api.config.get_max_retry_count(),
14171412
&[http::HTTP_STATUS_507_INSUFFICIENT_STORAGE],
14181413
)
14191414
.progress_bar_mode(ProgressBarMode::Request)
@@ -1472,7 +1467,7 @@ impl RegionSpecificApi<'_> {
14721467
.request(Method::Post, &path)?
14731468
.with_form_data(form)?
14741469
.with_retry(
1475-
self.api.api.config.get_max_retry_count().unwrap(),
1470+
self.api.api.config.get_max_retry_count(),
14761471
&[
14771472
http::HTTP_STATUS_502_BAD_GATEWAY,
14781473
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,

src/config.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
//! This module implements config access.
22
use std::env;
3+
use std::env::VarError;
34
use std::fs;
45
use std::fs::OpenOptions;
56
use std::io;
7+
use std::num::ParseIntError;
68
use std::path::{Path, PathBuf};
79
use std::sync::Arc;
810

@@ -26,6 +28,9 @@ use crate::utils::http::is_absolute_url;
2628
#[cfg(target_os = "macos")]
2729
use crate::utils::xcode;
2830

31+
const MAX_RETRIES_ENV_VAR: &str = "SENTRY_HTTP_MAX_RETRIES";
32+
const MAX_RETRIES_INI_KEY: &str = "max_retries";
33+
2934
/// Represents the auth information
3035
#[derive(Debug, Clone)]
3136
pub enum Auth {
@@ -462,14 +467,28 @@ impl Config {
462467
.unwrap_or(DEFAULT_MAX_DIF_ITEM_SIZE)
463468
}
464469

465-
pub fn get_max_retry_count(&self) -> Result<u32> {
466-
if env::var_os("SENTRY_HTTP_MAX_RETRIES").is_some() {
467-
Ok(env::var("SENTRY_HTTP_MAX_RETRIES")?.parse()?)
468-
} else if let Some(val) = self.ini.get_from(Some("http"), "max_retries") {
469-
Ok(val.parse()?)
470-
} else {
471-
Ok(DEFAULT_RETRIES)
472-
}
470+
/// Returns the configured maximum number of retries for failed HTTP requests.
471+
pub fn get_max_retry_count(&self) -> u32 {
472+
match max_retries_from_env() {
473+
Ok(Some(val)) => return val,
474+
Ok(None) => (),
475+
Err(e) => {
476+
warn!(
477+
"Ignoring invalid {MAX_RETRIES_ENV_VAR} environment variable: {}",
478+
e
479+
);
480+
}
481+
};
482+
483+
match max_retries_from_ini(&self.ini) {
484+
Ok(Some(val)) => return val,
485+
Ok(None) => (),
486+
Err(e) => {
487+
warn!("Ignoring invalid {MAX_RETRIES_INI_KEY} ini key: {}", e);
488+
}
489+
};
490+
491+
DEFAULT_RETRIES
473492
}
474493

475494
/// Return the DSN
@@ -520,6 +539,24 @@ impl Config {
520539
}
521540
}
522541

542+
/// Computes the maximum number of retries from the `SENTRY_HTTP_MAX_RETRIES` environment variable.
543+
/// Returns `Ok(None)` if the environment variable is not set, other errors are returned as is.
544+
fn max_retries_from_env() -> Result<Option<u32>> {
545+
match env::var(MAX_RETRIES_ENV_VAR) {
546+
Ok(val) => Ok(Some(val.parse()?)),
547+
Err(VarError::NotPresent) => Ok(None),
548+
Err(e) => Err(e.into()),
549+
}
550+
}
551+
552+
/// Computes the maximum number of retries from the `max_retries` ini key.
553+
/// Returns `Ok(None)` if the key is not set, other errors are returned as is.
554+
fn max_retries_from_ini(ini: &Ini) -> Result<Option<u32>, ParseIntError> {
555+
ini.get_from(Some("http"), MAX_RETRIES_INI_KEY)
556+
.map(|val| val.parse())
557+
.transpose()
558+
}
559+
523560
fn warn_about_conflicting_urls(token_url: &str, manually_configured_url: Option<&str>) {
524561
if let Some(manually_configured_url) = manually_configured_url {
525562
if manually_configured_url != token_url {

0 commit comments

Comments
 (0)