diff --git a/CHANGELOG.md b/CHANGELOG.md index 687e530546..638148d2c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ - Removed the `upload-proguard` subcommand's `--app-id`, `--version`, and `--version-code` arguments ([#2876](https://github.com/getsentry/sentry-cli/pull/2876)). Users using these arguments should stop using them, as they are unnecessary. The information passed to these arguments is no longer visible in Sentry. +### Fixes + +- Fixed misleading error message claiming the server doesn't support chunk uploading when the actual error was a non-existent organization ([#2930](https://github.com/getsentry/sentry-cli/pull/2930)). + ## 2.58.4 ### Fixes diff --git a/src/api/errors/api_error.rs b/src/api/errors/api_error.rs index 775f46d509..be6dda24fe 100644 --- a/src/api/errors/api_error.rs +++ b/src/api/errors/api_error.rs @@ -28,8 +28,6 @@ pub(in crate::api) enum ApiErrorKind { ProjectNotFound, #[error("Release not found. Ensure that you configured the correct release, project, and organization.")] ReleaseNotFound, - #[error("chunk upload endpoint not supported by sentry server")] - ChunkUploadNotSupported, #[error("API request failed")] RequestFailed, #[error("could not compress data")] @@ -63,6 +61,9 @@ impl ApiError { } } + // This method is currently only used in the macOS binary, there is no reason + // why not to expose it on other platforms, if we ever need it. + #[cfg(target_os = "macos")] pub(in crate::api) fn kind(&self) -> ApiErrorKind { self.inner } diff --git a/src/api/mod.rs b/src/api/mod.rs index 2778a2a364..f41459f406 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -956,21 +956,10 @@ impl<'a> AuthenticatedApi<'a> { } /// Get the server configuration for chunked file uploads. - pub fn get_chunk_upload_options(&self, org: &str) -> ApiResult> { + pub fn get_chunk_upload_options(&self, org: &str) -> ApiResult { let url = format!("/organizations/{}/chunk-upload/", PathArg(org)); - match self - .get(&url)? - .convert_rnf::(ApiErrorKind::ChunkUploadNotSupported) - { - Ok(options) => Ok(Some(options)), - Err(error) => { - if error.kind() == ApiErrorKind::ChunkUploadNotSupported { - Ok(None) - } else { - Err(error) - } - } - } + self.get(&url)? + .convert_rnf::(ApiErrorKind::OrganizationNotFound) } /// Request DIF assembling and processing from chunks. diff --git a/src/commands/build/upload.rs b/src/commands/build/upload.rs index 44a3f47e12..c1aa1bf0d6 100644 --- a/src/commands/build/upload.rs +++ b/src/commands/build/upload.rs @@ -607,12 +607,7 @@ fn upload_file( build_configuration.unwrap_or("unknown"), ); - let chunk_upload_options = api.get_chunk_upload_options(org)?.ok_or_else(|| { - anyhow!( - "The Sentry server lacks chunked uploading support, which \ - is required for build uploads. {SELF_HOSTED_ERROR_HINT}" - ) - })?; + let chunk_upload_options = api.get_chunk_upload_options(org)?; if !chunk_upload_options.supports(ChunkUploadCapability::PreprodArtifacts) { bail!( diff --git a/src/commands/dart_symbol_map/upload.rs b/src/commands/dart_symbol_map/upload.rs index 297a8db65e..2784060806 100644 --- a/src/commands/dart_symbol_map/upload.rs +++ b/src/commands/dart_symbol_map/upload.rs @@ -132,10 +132,7 @@ pub(super) fn execute(args: DartSymbolMapUploadArgs) -> Result<()> { ))?; let chunk_upload_options = api .authenticated()? - .get_chunk_upload_options(org)? - .ok_or_else(|| anyhow::anyhow!( - "server does not support chunked uploading. Please update your Sentry server." - ))?; + .get_chunk_upload_options(org)?; if !chunk_upload_options.supports(ChunkUploadCapability::DartSymbolMap) { bail!( diff --git a/src/commands/files/upload.rs b/src/commands/files/upload.rs index 469211e4f4..160de7e1ac 100644 --- a/src/commands/files/upload.rs +++ b/src/commands/files/upload.rs @@ -159,7 +159,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: None, wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, }; let path = Path::new(matches.get_one::("path").unwrap()); diff --git a/src/commands/react_native/appcenter.rs b/src/commands/react_native/appcenter.rs index 8205fec043..3d2d61564b 100644 --- a/src/commands/react_native/appcenter.rs +++ b/src/commands/react_native/appcenter.rs @@ -202,7 +202,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: None, wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, })?; } Some(dists) => { @@ -220,7 +220,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: None, wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, })?; } } diff --git a/src/commands/react_native/gradle.rs b/src/commands/react_native/gradle.rs index f8573c6ab4..e5a661f51a 100644 --- a/src/commands/react_native/gradle.rs +++ b/src/commands/react_native/gradle.rs @@ -129,7 +129,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: None, wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, })?; } } else { @@ -142,7 +142,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: None, wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, })?; } diff --git a/src/commands/react_native/xcode.rs b/src/commands/react_native/xcode.rs index a88f23486a..69b9822b1e 100644 --- a/src/commands/react_native/xcode.rs +++ b/src/commands/react_native/xcode.rs @@ -351,7 +351,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: None, wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, })?; } else { let (dist, release_name) = match (&dist_from_env, &release_from_env) { @@ -386,7 +386,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: None, wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, })?; } Some(dists) => { @@ -399,7 +399,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: None, wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, })?; } } diff --git a/src/commands/sourcemaps/upload.rs b/src/commands/sourcemaps/upload.rs index ecc98fa30c..b57b4f0c33 100644 --- a/src/commands/sourcemaps/upload.rs +++ b/src/commands/sourcemaps/upload.rs @@ -437,10 +437,10 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { log::warn!("The --use-artifact-bundle option and the SENTRY_FORCE_ARTIFACT_BUNDLES environment variable \ are both deprecated, and both will be removed in the next major version."); - if let Some(ref mut options) = chunk_upload_options { - if !options.supports(ChunkUploadCapability::ArtifactBundles) { - options.accept.push(ChunkUploadCapability::ArtifactBundles); - } + if !chunk_upload_options.supports(ChunkUploadCapability::ArtifactBundles) { + chunk_upload_options + .accept + .push(ChunkUploadCapability::ArtifactBundles); } } @@ -461,7 +461,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { note: matches.get_one::("note").map(String::as_str), wait, max_wait, - chunk_upload_options: chunk_upload_options.as_ref(), + chunk_upload_options: &chunk_upload_options, }; if matches.get_flag("strict") { diff --git a/src/commands/upload_proguard.rs b/src/commands/upload_proguard.rs index fd1af97484..2fa6ba4470 100644 --- a/src/commands/upload_proguard.rs +++ b/src/commands/upload_proguard.rs @@ -184,17 +184,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { authenticated_api = api.authenticated()?; (org, project) = config.get_org_and_project(matches)?; - let chunk_upload_options = authenticated_api - .get_chunk_upload_options(&org) - .map_err(|e| anyhow::anyhow!(e)) - .and_then(|options| { - options.ok_or_else(|| { - anyhow::anyhow!( - "server does not support chunked uploading. unset \ - {CHUNK_UPLOAD_ENV_VAR} to continue." - ) - }) - })?; + let chunk_upload_options = authenticated_api.get_chunk_upload_options(&org)?; proguard::chunk_upload(&mappings, chunk_upload_options, &org, &project)?; } else { diff --git a/src/utils/dif_upload/mod.rs b/src/utils/dif_upload/mod.rs index e576d3e343..bb4ccf3a32 100644 --- a/src/utils/dif_upload/mod.rs +++ b/src/utils/dif_upload/mod.rs @@ -1625,26 +1625,25 @@ impl<'a> DifUpload<'a> { } let api = Api::current(); - if let Some(chunk_options) = api.authenticated()?.get_chunk_upload_options(self.org)? { - if chunk_options.max_file_size > 0 { - self.max_file_size = chunk_options.max_file_size; - } - if chunk_options.max_wait > 0 { - self.max_wait = self - .max_wait - .min(Duration::from_secs(chunk_options.max_wait)); - } + let chunk_options = api.authenticated()?.get_chunk_upload_options(self.org)?; + if chunk_options.max_file_size > 0 { + self.max_file_size = chunk_options.max_file_size; + } + if chunk_options.max_wait > 0 { + self.max_wait = self + .max_wait + .min(Duration::from_secs(chunk_options.max_wait)); + } - self.pdbs_allowed = chunk_options.supports(ChunkUploadCapability::Pdbs); - self.portablepdbs_allowed = chunk_options.supports(ChunkUploadCapability::PortablePdbs); - self.sources_allowed = chunk_options.supports(ChunkUploadCapability::Sources); - self.bcsymbolmaps_allowed = chunk_options.supports(ChunkUploadCapability::BcSymbolmap); - self.il2cpp_mappings_allowed = chunk_options.supports(ChunkUploadCapability::Il2Cpp); + self.pdbs_allowed = chunk_options.supports(ChunkUploadCapability::Pdbs); + self.portablepdbs_allowed = chunk_options.supports(ChunkUploadCapability::PortablePdbs); + self.sources_allowed = chunk_options.supports(ChunkUploadCapability::Sources); + self.bcsymbolmaps_allowed = chunk_options.supports(ChunkUploadCapability::BcSymbolmap); + self.il2cpp_mappings_allowed = chunk_options.supports(ChunkUploadCapability::Il2Cpp); - if chunk_options.supports(ChunkUploadCapability::DebugFiles) { - self.validate_capabilities(); - return upload_difs_chunked(self, chunk_options); - } + if chunk_options.supports(ChunkUploadCapability::DebugFiles) { + self.validate_capabilities(); + return upload_difs_chunked(self, chunk_options); } self.validate_capabilities(); diff --git a/src/utils/file_upload.rs b/src/utils/file_upload.rs index cb837beb3e..95f03e90af 100644 --- a/src/utils/file_upload.rs +++ b/src/utils/file_upload.rs @@ -29,9 +29,6 @@ use crate::utils::source_bundle; use super::file_search::ReleaseFileMatch; -/// Fallback concurrency for release file uploads. -static DEFAULT_CONCURRENCY: usize = 4; - /// Old versions of Sentry cannot assemble artifact bundles straight away, they require /// that those bundles are associated to a release. /// @@ -42,11 +39,10 @@ pub fn initialize_legacy_release_upload(context: &UploadContext) -> Result<()> { // need to do anything here. Artifact bundles will also only work // if a project is provided which is technically unnecessary for the // legacy upload though it will unlikely to be what users want. + let chunk_options = context.chunk_upload_options; if context.projects.is_some() - && context.chunk_upload_options.is_some_and(|x| { - x.supports(ChunkUploadCapability::ArtifactBundles) - || x.supports(ChunkUploadCapability::ArtifactBundlesV2) - }) + && (chunk_options.supports(ChunkUploadCapability::ArtifactBundles) + || chunk_options.supports(ChunkUploadCapability::ArtifactBundlesV2)) { return Ok(()); } @@ -75,19 +71,8 @@ pub fn initialize_legacy_release_upload(context: &UploadContext) -> Result<()> { ..Default::default() }, )?; - } else if context.chunk_upload_options.is_some() { - bail!("This version of Sentry does not support artifact bundles. A release slug is required (provide with --release or by setting the SENTRY_RELEASE environment variable)"); } else { - // We got a 404 when trying to get the chunk options from the server. Most likely, the - // organization does not exist, though old self-hosted Sentry servers may also completely - // lack support for chunked uploads. - bail!( - "The provided organization \"{}\" does not exist. If you are using a self-hosted \ - Sentry server, it is also possible that your Sentry server lacks support for \ - uploading artifact bundles, in which case you need to provide a release slug with \ - --release or by setting the SENTRY_RELEASE environment variable.", - context.org - ); + bail!("This version of Sentry does not support artifact bundles. A release slug is required (provide with --release or by setting the SENTRY_RELEASE environment variable)"); } Ok(()) } @@ -101,7 +86,7 @@ pub struct UploadContext<'a> { pub note: Option<&'a str>, pub wait: bool, pub max_wait: Duration, - pub chunk_upload_options: Option<&'a ChunkServerOptions>, + pub chunk_upload_options: &'a ChunkServerOptions, } impl UploadContext<'_> { @@ -372,11 +357,17 @@ impl<'a> FileUpload<'a> { // multiple projects OK initialize_legacy_release_upload(self.context)?; - if let Some(chunk_options) = self.context.chunk_upload_options { - if chunk_options.supports(ChunkUploadCapability::ReleaseFiles) { - // multiple projects OK - return upload_files_chunked(self.context, &self.files, chunk_options); - } + if self + .context + .chunk_upload_options + .supports(ChunkUploadCapability::ReleaseFiles) + { + // multiple projects OK + return upload_files_chunked( + self.context, + &self.files, + self.context.chunk_upload_options, + ); } log::warn!( @@ -398,10 +389,7 @@ impl<'a> FileUpload<'a> { ); } - let concurrency = self - .context - .chunk_upload_options - .map_or(DEFAULT_CONCURRENCY, |o| usize::from(o.concurrency)); + let concurrency = self.context.chunk_upload_options.concurrency as usize; let legacy_context = &self.context.try_into().map_err(|e| { anyhow::anyhow!( @@ -701,15 +689,16 @@ fn print_upload_context_details(context: &UploadContext) { style("> Dist:").dim(), style(context.dist.unwrap_or("None")).yellow() ); - let upload_type = match context.chunk_upload_options { - None => "single file", - Some(opts) - if opts.supports(ChunkUploadCapability::ArtifactBundles) - || opts.supports(ChunkUploadCapability::ArtifactBundlesV2) => - { - "artifact bundle" - } - _ => "release bundle", + let upload_type = if context + .chunk_upload_options + .supports(ChunkUploadCapability::ArtifactBundles) + || context + .chunk_upload_options + .supports(ChunkUploadCapability::ArtifactBundlesV2) + { + "artifact bundle" + } else { + "release bundle" }; println!( "{} {}",