sentry-cli 3.2.0__tar.gz → 3.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/Cargo.lock +1 -1
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/Cargo.toml +1 -1
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/PKG-INFO +1 -1
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/sentry_cli.egg-info/PKG-INFO +1 -1
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/errors/mod.rs +8 -13
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/mod.rs +55 -9
- sentry_cli-3.2.2/src/commands/dart_symbol_map/mod.rs +27 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/dart_symbol_map/upload.rs +35 -46
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/derive_parser.rs +0 -2
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/logs/mod.rs +1 -3
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/constants.rs +3 -0
- sentry_cli-3.2.0/src/commands/dart_symbol_map/mod.rs +0 -47
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/LICENSE +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/MANIFEST.in +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/README.md +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/AGENTS.md +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/CLAUDE.md +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/Cargo.toml +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/build.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Info.plist +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Products/Applications/DemoApp.app/Assets.car +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/src/lib.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/build.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/pyproject.toml +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/sentry_cli.egg-info/SOURCES.txt +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/sentry_cli.egg-info/dependency_links.txt +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/sentry_cli.egg-info/top_level.txt +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/setup.cfg +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/setup.py +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/AGENTS.md +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/CLAUDE.md +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/connection_manager.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/artifact.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/build.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/compression.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/dif.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/file_state.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/upload/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/upload/options.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/deploy.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/encoding.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/envelopes_api.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/errors/api_error.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/errors/sentry_error.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/pagination.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/serialization.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/bashsupport.sh +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/bash_hook.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/build/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/build/upload.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/bundle_jvm.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/bundle_sources.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/check.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/find.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/print_sources.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/upload.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/deploys/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/deploys/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/deploys/new.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/events/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/events/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/info.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/mute.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/resolve.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/unresolve.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/login.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/logs/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/monitors/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/monitors/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/monitors/run.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/organizations/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/organizations/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/projects/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/projects/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/react_native/gradle.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/react_native/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/react_native/xcode.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/archive.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/delete.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/finalize.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/info.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/new.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/propose_version.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/restore.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/set_commits.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/repos/list.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/repos/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_envelope.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_event.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_metric/common_args.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_metric/increment.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_metric/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_metric/set.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/sourcemaps/inject.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/sourcemaps/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/sourcemaps/resolve.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/sourcemaps/upload.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/uninstall.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/update.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/upload_dif.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/upload_dsym.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/upload_proguard.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/config.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/main.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/android.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/args.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/auth_token_impl.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/error.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/org_auth_token.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/redacting.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/test.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/user_auth_token.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/build/apple.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/build/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/build/normalize.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/build/validation.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/chunks/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/chunks/options.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/chunks/types.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/chunks/upload.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/ci.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/cordova.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/dif.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/dif_upload/error.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/dif_upload/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/event.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/file_search.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/file_upload.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/formatting.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/fs.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/http.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/logging.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/non_empty.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/progress.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/proguard/mapping.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/proguard/mod.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/proguard/upload.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/releases.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/retry.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_default_twenty.snap +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_ignore_missing.snap +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_base.snap +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_previous_commit.snap +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__get_commits_from_git.snap +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/source_bundle.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/sourcemaps/inject.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/sourcemaps.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/system.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/ui.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/update.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/value_parsers.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/vcs.rs +0 -0
- {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/xcode.rs +0 -0
|
@@ -14,17 +14,12 @@ pub(super) struct ProjectRenamedError(pub(super) String);
|
|
|
14
14
|
pub(super) type ApiResult<T> = Result<T, ApiError>;
|
|
15
15
|
|
|
16
16
|
#[derive(Debug, thiserror::Error)]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
body: ApiResponse,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
pub fn into_body(self) -> ApiResponse {
|
|
28
|
-
self.body
|
|
29
|
-
}
|
|
17
|
+
pub(super) enum RetryError {
|
|
18
|
+
#[error("request failed with retryable status code {}", body.status)]
|
|
19
|
+
Status { body: ApiResponse },
|
|
20
|
+
#[error("request failed with retryable error: {source}")]
|
|
21
|
+
ApiError {
|
|
22
|
+
#[from]
|
|
23
|
+
source: ApiError,
|
|
24
|
+
},
|
|
30
25
|
}
|
|
@@ -15,11 +15,12 @@ mod serialization;
|
|
|
15
15
|
use std::borrow::Cow;
|
|
16
16
|
use std::cell::RefCell;
|
|
17
17
|
use std::collections::HashMap;
|
|
18
|
+
use std::error::Error as _;
|
|
18
19
|
#[cfg(any(target_os = "macos", not(feature = "managed")))]
|
|
19
20
|
use std::fs::File;
|
|
20
21
|
use std::io::{self, Read as _, Write};
|
|
21
22
|
use std::rc::Rc;
|
|
22
|
-
use std::sync::Arc;
|
|
23
|
+
use std::sync::{Arc, LazyLock};
|
|
23
24
|
use std::{fmt, thread};
|
|
24
25
|
|
|
25
26
|
use anyhow::{Context as _, Result};
|
|
@@ -39,11 +40,12 @@ use serde::{Deserialize, Serialize};
|
|
|
39
40
|
use sha1_smol::Digest;
|
|
40
41
|
use symbolic::common::DebugId;
|
|
41
42
|
use symbolic::debuginfo::ObjectKind;
|
|
43
|
+
use url::Url;
|
|
42
44
|
use uuid::Uuid;
|
|
43
45
|
|
|
44
46
|
use crate::api::errors::{ProjectRenamedError, RetryError};
|
|
45
47
|
use crate::config::{Auth, Config};
|
|
46
|
-
use crate::constants::{ARCH, EXT, PLATFORM, RELEASE_REGISTRY_LATEST_URL, VERSION};
|
|
48
|
+
use crate::constants::{ARCH, DEFAULT_HOST, EXT, PLATFORM, RELEASE_REGISTRY_LATEST_URL, VERSION};
|
|
47
49
|
use crate::utils::http::{self, is_absolute_url};
|
|
48
50
|
use crate::utils::non_empty::NonEmptySlice;
|
|
49
51
|
use crate::utils::progress::{ProgressBar, ProgressBarMode};
|
|
@@ -111,6 +113,7 @@ pub struct ApiRequest {
|
|
|
111
113
|
is_authenticated: bool,
|
|
112
114
|
body: Option<Vec<u8>>,
|
|
113
115
|
progress_bar_mode: ProgressBarMode,
|
|
116
|
+
url: String,
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
/// Represents an API response.
|
|
@@ -180,7 +183,7 @@ impl Api {
|
|
|
180
183
|
region_url: Option<&str>,
|
|
181
184
|
) -> ApiResult<ApiRequest> {
|
|
182
185
|
let (url, auth) = self.resolve_base_url_and_auth(url, region_url)?;
|
|
183
|
-
self.construct_api_request(method,
|
|
186
|
+
self.construct_api_request(method, url, auth)
|
|
184
187
|
}
|
|
185
188
|
|
|
186
189
|
fn resolve_base_url_and_auth(
|
|
@@ -210,7 +213,7 @@ impl Api {
|
|
|
210
213
|
fn construct_api_request(
|
|
211
214
|
&self,
|
|
212
215
|
method: Method,
|
|
213
|
-
url:
|
|
216
|
+
url: String,
|
|
214
217
|
auth: Option<&Auth>,
|
|
215
218
|
) -> ApiResult<ApiRequest> {
|
|
216
219
|
let mut handle = self
|
|
@@ -1161,7 +1164,7 @@ impl ApiRequest {
|
|
|
1161
1164
|
fn create(
|
|
1162
1165
|
mut handle: r2d2::PooledConnection<CurlConnectionManager>,
|
|
1163
1166
|
method: &Method,
|
|
1164
|
-
url:
|
|
1167
|
+
url: String,
|
|
1165
1168
|
auth: Option<&Auth>,
|
|
1166
1169
|
pipeline_env: Option<String>,
|
|
1167
1170
|
global_headers: Option<Vec<String>>,
|
|
@@ -1196,7 +1199,7 @@ impl ApiRequest {
|
|
|
1196
1199
|
Method::Delete => handle.custom_request("DELETE")?,
|
|
1197
1200
|
}
|
|
1198
1201
|
|
|
1199
|
-
handle.url(url)?;
|
|
1202
|
+
handle.url(&url)?;
|
|
1200
1203
|
|
|
1201
1204
|
let request = ApiRequest {
|
|
1202
1205
|
handle,
|
|
@@ -1204,6 +1207,7 @@ impl ApiRequest {
|
|
|
1204
1207
|
is_authenticated: false,
|
|
1205
1208
|
body: None,
|
|
1206
1209
|
progress_bar_mode: ProgressBarMode::Disabled,
|
|
1210
|
+
url,
|
|
1207
1211
|
};
|
|
1208
1212
|
|
|
1209
1213
|
let request = match auth {
|
|
@@ -1313,11 +1317,22 @@ impl ApiRequest {
|
|
|
1313
1317
|
debug!("retry number {retry_number}, max retries: {max_retries}");
|
|
1314
1318
|
*retry_number += 1;
|
|
1315
1319
|
|
|
1316
|
-
let mut rv = self.send_into(&mut out)
|
|
1320
|
+
let mut rv = self.send_into(&mut out).map_err(|err| {
|
|
1321
|
+
// Retry DNS failures for sentry.io, as these likely indicate
|
|
1322
|
+
// a network issue. DNS failures for other domains should not
|
|
1323
|
+
// be retried, to avoid masking configuration problems (e.g.
|
|
1324
|
+
// if the user has mistyped their self-hosted URL).
|
|
1325
|
+
if is_dns_error(&err) && self.is_sentry_io_host() {
|
|
1326
|
+
anyhow::anyhow!(RetryError::from(err))
|
|
1327
|
+
} else {
|
|
1328
|
+
anyhow::anyhow!(err)
|
|
1329
|
+
}
|
|
1330
|
+
})?;
|
|
1331
|
+
|
|
1317
1332
|
rv.body = Some(out);
|
|
1318
1333
|
|
|
1319
1334
|
if RETRY_STATUS_CODES.contains(&rv.status) {
|
|
1320
|
-
anyhow::bail!(RetryError::
|
|
1335
|
+
anyhow::bail!(RetryError::Status { body: rv });
|
|
1321
1336
|
}
|
|
1322
1337
|
|
|
1323
1338
|
Ok(rv)
|
|
@@ -1336,10 +1351,41 @@ impl ApiRequest {
|
|
|
1336
1351
|
})
|
|
1337
1352
|
.call()
|
|
1338
1353
|
.or_else(|err| match err.downcast::<RetryError>() {
|
|
1339
|
-
Ok(
|
|
1354
|
+
Ok(RetryError::Status { body }) => Ok(body),
|
|
1355
|
+
Ok(RetryError::ApiError { source }) => Err(source),
|
|
1340
1356
|
Err(err) => Err(ApiError::with_source(ApiErrorKind::RequestFailed, err)),
|
|
1341
1357
|
})
|
|
1342
1358
|
}
|
|
1359
|
+
|
|
1360
|
+
/// Determines whether a URL has a sentry.io host (including subdomains).
|
|
1361
|
+
fn is_sentry_io_host(&self) -> bool {
|
|
1362
|
+
/// A regex which matches exactly "sentry.io" and hostnames ending in
|
|
1363
|
+
/// ".sentry.io".
|
|
1364
|
+
static SENTRY_IO_HOST_RE: LazyLock<Regex> = LazyLock::new(|| {
|
|
1365
|
+
Regex::new(&format!(r"^(\S*\.)?{}$", regex::escape(DEFAULT_HOST)))
|
|
1366
|
+
.expect("regex is valid")
|
|
1367
|
+
});
|
|
1368
|
+
|
|
1369
|
+
Url::parse(&self.url)
|
|
1370
|
+
.ok()
|
|
1371
|
+
.map(|url| {
|
|
1372
|
+
url.host_str()
|
|
1373
|
+
.is_some_and(|host| SENTRY_IO_HOST_RE.is_match(host))
|
|
1374
|
+
})
|
|
1375
|
+
.unwrap_or(false)
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
/// Returns true if the error source chain contains a curl DNS resolution error.
|
|
1380
|
+
fn is_dns_error(err: &ApiError) -> bool {
|
|
1381
|
+
let mut current = err.source();
|
|
1382
|
+
while let Some(error) = current {
|
|
1383
|
+
if let Some(curl_err) = error.downcast_ref::<curl::Error>() {
|
|
1384
|
+
return curl_err.is_couldnt_resolve_host();
|
|
1385
|
+
}
|
|
1386
|
+
current = error.source();
|
|
1387
|
+
}
|
|
1388
|
+
false
|
|
1343
1389
|
}
|
|
1344
1390
|
|
|
1345
1391
|
impl ApiResponse {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
use anyhow::Result;
|
|
2
|
+
use clap::{ArgMatches, Command};
|
|
3
|
+
|
|
4
|
+
use crate::utils::args::ArgExt as _;
|
|
5
|
+
|
|
6
|
+
pub mod upload;
|
|
7
|
+
|
|
8
|
+
const GROUP_ABOUT: &str = "Manage Dart/Flutter symbol maps for Sentry.";
|
|
9
|
+
|
|
10
|
+
pub(super) fn make_command(mut command: Command) -> Command {
|
|
11
|
+
command = command
|
|
12
|
+
.about(GROUP_ABOUT)
|
|
13
|
+
.subcommand_required(true)
|
|
14
|
+
.arg_required_else_help(true)
|
|
15
|
+
.org_arg()
|
|
16
|
+
.project_arg(false);
|
|
17
|
+
|
|
18
|
+
command = command.subcommand(upload::make_command(Command::new("upload")));
|
|
19
|
+
command
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub(super) fn execute(matches: &ArgMatches) -> Result<()> {
|
|
23
|
+
if let Some(sub_matches) = matches.subcommand_matches("upload") {
|
|
24
|
+
return upload::execute(sub_matches);
|
|
25
|
+
}
|
|
26
|
+
unreachable!();
|
|
27
|
+
}
|
|
@@ -4,7 +4,7 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
|
|
|
4
4
|
use std::path::Path;
|
|
5
5
|
|
|
6
6
|
use anyhow::{bail, Context as _, Result};
|
|
7
|
-
use clap::
|
|
7
|
+
use clap::{Arg, ArgMatches, Command};
|
|
8
8
|
|
|
9
9
|
use crate::api::Api;
|
|
10
10
|
use crate::config::Config;
|
|
@@ -42,32 +42,37 @@ impl Assemblable for DartSymbolMapObject<'_> {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
45
|
+
const MAPPING_ARG: &str = "mapping";
|
|
46
|
+
const DEBUG_FILE_ARG: &str = "debug_file";
|
|
47
|
+
|
|
48
|
+
pub(super) fn make_command(command: Command) -> Command {
|
|
49
|
+
command
|
|
50
|
+
.about("Upload a Dart/Flutter symbol map (dartsymbolmap) for deobfuscating Dart exception types.")
|
|
51
|
+
.long_about(
|
|
52
|
+
"Upload a Dart/Flutter symbol map (dartsymbolmap) for deobfuscating Dart exception types.{n}{n}Examples:{n} sentry-cli dart-symbol-map upload --org my-org --project my-proj path/to/dartsymbolmap.json path/to/debug/file{n}{n}The mapping must be a JSON array of strings with an even number of entries (pairs).{n}The debug file must contain exactly one Debug ID. {n}{n}\
|
|
53
|
+
This command is supported on Sentry SaaS and self-hosted versions ≥25.8.0.",
|
|
54
|
+
)
|
|
55
|
+
.arg(
|
|
56
|
+
Arg::new(MAPPING_ARG)
|
|
57
|
+
.value_name("MAPPING")
|
|
58
|
+
.required(true)
|
|
59
|
+
.help("Path to the dartsymbolmap JSON file (e.g. dartsymbolmap.json). Must be a JSON array of strings with an even number of entries (pairs)."),
|
|
60
|
+
)
|
|
61
|
+
.arg(
|
|
62
|
+
Arg::new(DEBUG_FILE_ARG)
|
|
63
|
+
.value_name("DEBUG_FILE")
|
|
64
|
+
.required(true)
|
|
65
|
+
.help("Path to the corresponding debug file to extract the Debug ID from. The file must contain exactly one Debug ID."),
|
|
66
|
+
)
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
pub(super) fn execute(
|
|
69
|
-
let mapping_path =
|
|
70
|
-
|
|
69
|
+
pub(super) fn execute(matches: &ArgMatches) -> Result<()> {
|
|
70
|
+
let mapping_path = matches
|
|
71
|
+
.get_one::<String>(MAPPING_ARG)
|
|
72
|
+
.expect("required by clap");
|
|
73
|
+
let debug_file_path = matches
|
|
74
|
+
.get_one::<String>(DEBUG_FILE_ARG)
|
|
75
|
+
.expect("required by clap");
|
|
71
76
|
|
|
72
77
|
// Extract Debug ID(s) from the provided debug file
|
|
73
78
|
let dif = DifFile::open_path(debug_file_path, None)?;
|
|
@@ -101,8 +106,7 @@ pub(super) fn execute(args: DartSymbolMapUploadArgs) -> Result<()> {
|
|
|
101
106
|
let file_name = Path::new(mapping_path)
|
|
102
107
|
.file_name()
|
|
103
108
|
.and_then(OsStr::to_str)
|
|
104
|
-
.unwrap_or(mapping_path)
|
|
105
|
-
;
|
|
109
|
+
.unwrap_or(mapping_path);
|
|
106
110
|
|
|
107
111
|
let mapping_len = mapping_file_bytes.len();
|
|
108
112
|
let object = DartSymbolMapObject {
|
|
@@ -113,27 +117,12 @@ pub(super) fn execute(args: DartSymbolMapUploadArgs) -> Result<()> {
|
|
|
113
117
|
|
|
114
118
|
// Prepare chunked upload
|
|
115
119
|
let api = Api::current();
|
|
116
|
-
// Resolve org and project like logs: prefer args, fallback to defaults
|
|
117
120
|
let config = Config::current();
|
|
118
|
-
let
|
|
119
|
-
let
|
|
120
|
-
.org
|
|
121
|
-
.as_ref()
|
|
122
|
-
.or(default_org.as_ref())
|
|
123
|
-
.ok_or_else(|| anyhow::anyhow!(
|
|
124
|
-
"No organization specified. Please specify an organization using the --org argument."
|
|
125
|
-
))?;
|
|
126
|
-
let project = args
|
|
127
|
-
.project
|
|
128
|
-
.as_ref()
|
|
129
|
-
.or(default_project.as_ref())
|
|
130
|
-
.ok_or_else(|| anyhow::anyhow!(
|
|
131
|
-
"No project specified. Use --project or set a default in config."
|
|
132
|
-
))?;
|
|
121
|
+
let org = config.get_org(matches)?;
|
|
122
|
+
let project = config.get_project(matches)?;
|
|
133
123
|
let chunk_upload_options = api
|
|
134
124
|
.authenticated()?
|
|
135
|
-
.get_chunk_upload_options(org)?;
|
|
136
|
-
|
|
125
|
+
.get_chunk_upload_options(&org)?;
|
|
137
126
|
|
|
138
127
|
// Early file size check against server or default limits (same as debug files)
|
|
139
128
|
let effective_max_file_size = if chunk_upload_options.max_file_size > 0 {
|
|
@@ -148,7 +137,7 @@ pub(super) fn execute(args: DartSymbolMapUploadArgs) -> Result<()> {
|
|
|
148
137
|
);
|
|
149
138
|
}
|
|
150
139
|
|
|
151
|
-
let options = ChunkOptions::new(chunk_upload_options, org, project)
|
|
140
|
+
let options = ChunkOptions::new(chunk_upload_options, &org, &project)
|
|
152
141
|
.with_max_wait(DEFAULT_MAX_WAIT);
|
|
153
142
|
|
|
154
143
|
let chunked = Chunked::from(object, options.server_options().chunk_size);
|
|
@@ -2,7 +2,6 @@ use crate::utils::auth_token::AuthToken;
|
|
|
2
2
|
use crate::utils::value_parsers::{auth_token_parser, kv_parser};
|
|
3
3
|
use clap::{ArgAction::SetTrue, Parser, Subcommand};
|
|
4
4
|
|
|
5
|
-
use super::dart_symbol_map::DartSymbolMapArgs;
|
|
6
5
|
use super::logs::LogsArgs;
|
|
7
6
|
|
|
8
7
|
#[derive(Parser)]
|
|
@@ -38,5 +37,4 @@ pub(super) struct SentryCLI {
|
|
|
38
37
|
#[derive(Subcommand)]
|
|
39
38
|
pub(super) enum SentryCLICommand {
|
|
40
39
|
Logs(LogsArgs),
|
|
41
|
-
DartSymbolMap(DartSymbolMapArgs),
|
|
42
40
|
}
|
|
@@ -39,9 +39,7 @@ pub(super) fn make_command(command: Command) -> Command {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
pub(super) fn execute(_: &ArgMatches) -> Result<()> {
|
|
42
|
-
let SentryCLICommand::Logs(LogsArgs { subcommand }) = SentryCLI::parse().command
|
|
43
|
-
unreachable!("expected logs subcommand");
|
|
44
|
-
};
|
|
42
|
+
let SentryCLICommand::Logs(LogsArgs { subcommand }) = SentryCLI::parse().command;
|
|
45
43
|
eprintln!("{BETA_WARNING}");
|
|
46
44
|
|
|
47
45
|
match subcommand {
|
|
@@ -8,6 +8,9 @@ pub const APP_NAME: &str = "sentrycli";
|
|
|
8
8
|
/// The default API URL
|
|
9
9
|
pub const DEFAULT_URL: &str = "https://sentry.io/";
|
|
10
10
|
|
|
11
|
+
/// The default API host
|
|
12
|
+
pub const DEFAULT_HOST: &str = "sentry.io";
|
|
13
|
+
|
|
11
14
|
/// The version of the library
|
|
12
15
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
13
16
|
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
use anyhow::Result;
|
|
2
|
-
use clap::{ArgMatches, Args, Command, Parser as _, Subcommand};
|
|
3
|
-
|
|
4
|
-
pub mod upload;
|
|
5
|
-
|
|
6
|
-
const GROUP_ABOUT: &str = "Manage Dart/Flutter symbol maps for Sentry.";
|
|
7
|
-
const UPLOAD_ABOUT: &str =
|
|
8
|
-
"Upload a Dart/Flutter symbol map (dartsymbolmap) for deobfuscating Dart exception types.";
|
|
9
|
-
const UPLOAD_LONG_ABOUT: &str =
|
|
10
|
-
"Upload a Dart/Flutter symbol map (dartsymbolmap) for deobfuscating Dart exception types.{n}{n}Examples:{n} sentry-cli dart-symbol-map upload --org my-org --project my-proj path/to/dartsymbolmap.json path/to/debug/file{n}{n}The mapping must be a JSON array of strings with an even number of entries (pairs).{n}The debug file must contain exactly one Debug ID. {n}{n}\
|
|
11
|
-
This command is supported on Sentry SaaS and self-hosted versions ≥25.8.0.";
|
|
12
|
-
|
|
13
|
-
#[derive(Args)]
|
|
14
|
-
pub(super) struct DartSymbolMapArgs {
|
|
15
|
-
#[command(subcommand)]
|
|
16
|
-
pub(super) subcommand: DartSymbolMapSubcommand,
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
#[derive(Subcommand)]
|
|
20
|
-
#[command(about = GROUP_ABOUT)]
|
|
21
|
-
pub(super) enum DartSymbolMapSubcommand {
|
|
22
|
-
#[command(about = UPLOAD_ABOUT)]
|
|
23
|
-
#[command(long_about = UPLOAD_LONG_ABOUT)]
|
|
24
|
-
Upload(upload::DartSymbolMapUploadArgs),
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
pub(super) fn make_command(command: Command) -> Command {
|
|
28
|
-
DartSymbolMapSubcommand::augment_subcommands(
|
|
29
|
-
command
|
|
30
|
-
.about(GROUP_ABOUT)
|
|
31
|
-
.subcommand_required(true)
|
|
32
|
-
.arg_required_else_help(true),
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
pub(super) fn execute(_: &ArgMatches) -> Result<()> {
|
|
37
|
-
let subcommand = match crate::commands::derive_parser::SentryCLI::parse().command {
|
|
38
|
-
crate::commands::derive_parser::SentryCLICommand::DartSymbolMap(DartSymbolMapArgs {
|
|
39
|
-
subcommand,
|
|
40
|
-
}) => subcommand,
|
|
41
|
-
_ => unreachable!("expected dart-symbol-map subcommand"),
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
match subcommand {
|
|
45
|
-
DartSymbolMapSubcommand::Upload(args) => upload::execute(args),
|
|
46
|
-
}
|
|
47
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|