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.
Files changed (170) hide show
  1. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/Cargo.lock +1 -1
  2. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/Cargo.toml +1 -1
  3. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/PKG-INFO +1 -1
  4. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/sentry_cli.egg-info/PKG-INFO +1 -1
  5. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/errors/mod.rs +8 -13
  6. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/mod.rs +55 -9
  7. sentry_cli-3.2.2/src/commands/dart_symbol_map/mod.rs +27 -0
  8. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/dart_symbol_map/upload.rs +35 -46
  9. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/derive_parser.rs +0 -2
  10. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/logs/mod.rs +1 -3
  11. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/constants.rs +3 -0
  12. sentry_cli-3.2.0/src/commands/dart_symbol_map/mod.rs +0 -47
  13. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/LICENSE +0 -0
  14. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/MANIFEST.in +0 -0
  15. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/README.md +0 -0
  16. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/AGENTS.md +0 -0
  17. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/CLAUDE.md +0 -0
  18. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/Cargo.toml +0 -0
  19. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/build.rs +0 -0
  20. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
  21. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
  22. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
  23. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
  24. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
  25. {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
  26. {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
  27. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
  28. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/apple-catalog-parsing/src/lib.rs +0 -0
  29. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/build.rs +0 -0
  30. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/pyproject.toml +0 -0
  31. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/sentry_cli.egg-info/SOURCES.txt +0 -0
  32. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/sentry_cli.egg-info/dependency_links.txt +0 -0
  33. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/sentry_cli.egg-info/top_level.txt +0 -0
  34. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/setup.cfg +0 -0
  35. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/setup.py +0 -0
  36. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/AGENTS.md +0 -0
  37. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/CLAUDE.md +0 -0
  38. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/connection_manager.rs +0 -0
  39. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/artifact.rs +0 -0
  40. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/build.rs +0 -0
  41. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/compression.rs +0 -0
  42. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/dif.rs +0 -0
  43. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/file_state.rs +0 -0
  44. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
  45. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/mod.rs +0 -0
  46. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/upload/mod.rs +0 -0
  47. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/chunking/upload/options.rs +0 -0
  48. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/deploy.rs +0 -0
  49. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/data_types/mod.rs +0 -0
  50. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/encoding.rs +0 -0
  51. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/envelopes_api.rs +0 -0
  52. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/errors/api_error.rs +0 -0
  53. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/errors/sentry_error.rs +0 -0
  54. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/pagination.rs +0 -0
  55. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/api/serialization.rs +0 -0
  56. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/bashsupport.sh +0 -0
  57. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/bash_hook.rs +0 -0
  58. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/build/mod.rs +0 -0
  59. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/build/upload.rs +0 -0
  60. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/bundle_jvm.rs +0 -0
  61. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/bundle_sources.rs +0 -0
  62. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/check.rs +0 -0
  63. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/find.rs +0 -0
  64. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/mod.rs +0 -0
  65. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/print_sources.rs +0 -0
  66. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/debug_files/upload.rs +0 -0
  67. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/deploys/list.rs +0 -0
  68. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/deploys/mod.rs +0 -0
  69. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/deploys/new.rs +0 -0
  70. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/events/list.rs +0 -0
  71. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/events/mod.rs +0 -0
  72. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/info.rs +0 -0
  73. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/list.rs +0 -0
  74. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/mod.rs +0 -0
  75. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/mute.rs +0 -0
  76. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/resolve.rs +0 -0
  77. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/issues/unresolve.rs +0 -0
  78. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/login.rs +0 -0
  79. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/logs/list.rs +0 -0
  80. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/mod.rs +0 -0
  81. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/monitors/list.rs +0 -0
  82. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/monitors/mod.rs +0 -0
  83. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/monitors/run.rs +0 -0
  84. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/organizations/list.rs +0 -0
  85. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/organizations/mod.rs +0 -0
  86. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/projects/list.rs +0 -0
  87. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/projects/mod.rs +0 -0
  88. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/react_native/gradle.rs +0 -0
  89. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/react_native/mod.rs +0 -0
  90. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/react_native/xcode.rs +0 -0
  91. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/archive.rs +0 -0
  92. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/delete.rs +0 -0
  93. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/finalize.rs +0 -0
  94. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/info.rs +0 -0
  95. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/list.rs +0 -0
  96. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/mod.rs +0 -0
  97. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/new.rs +0 -0
  98. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/propose_version.rs +0 -0
  99. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/restore.rs +0 -0
  100. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/releases/set_commits.rs +0 -0
  101. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/repos/list.rs +0 -0
  102. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/repos/mod.rs +0 -0
  103. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_envelope.rs +0 -0
  104. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_event.rs +0 -0
  105. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_metric/common_args.rs +0 -0
  106. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_metric/increment.rs +0 -0
  107. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_metric/mod.rs +0 -0
  108. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/send_metric/set.rs +0 -0
  109. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/sourcemaps/inject.rs +0 -0
  110. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/sourcemaps/mod.rs +0 -0
  111. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/sourcemaps/resolve.rs +0 -0
  112. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/sourcemaps/upload.rs +0 -0
  113. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/uninstall.rs +0 -0
  114. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/update.rs +0 -0
  115. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/upload_dif.rs +0 -0
  116. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/upload_dsym.rs +0 -0
  117. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/commands/upload_proguard.rs +0 -0
  118. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/config.rs +0 -0
  119. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/main.rs +0 -0
  120. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/android.rs +0 -0
  121. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/args.rs +0 -0
  122. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/auth_token_impl.rs +0 -0
  123. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/error.rs +0 -0
  124. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/mod.rs +0 -0
  125. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/org_auth_token.rs +0 -0
  126. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/redacting.rs +0 -0
  127. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/test.rs +0 -0
  128. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/auth_token/user_auth_token.rs +0 -0
  129. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/build/apple.rs +0 -0
  130. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/build/mod.rs +0 -0
  131. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/build/normalize.rs +0 -0
  132. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/build/validation.rs +0 -0
  133. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/chunks/mod.rs +0 -0
  134. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/chunks/options.rs +0 -0
  135. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/chunks/types.rs +0 -0
  136. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/chunks/upload.rs +0 -0
  137. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/ci.rs +0 -0
  138. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/cordova.rs +0 -0
  139. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/dif.rs +0 -0
  140. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/dif_upload/error.rs +0 -0
  141. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/dif_upload/mod.rs +0 -0
  142. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/event.rs +0 -0
  143. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/file_search.rs +0 -0
  144. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/file_upload.rs +0 -0
  145. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/formatting.rs +0 -0
  146. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/fs.rs +0 -0
  147. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/http.rs +0 -0
  148. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/logging.rs +0 -0
  149. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/mod.rs +0 -0
  150. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/non_empty.rs +0 -0
  151. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/progress.rs +0 -0
  152. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/proguard/mapping.rs +0 -0
  153. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/proguard/mod.rs +0 -0
  154. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/proguard/upload.rs +0 -0
  155. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/releases.rs +0 -0
  156. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/retry.rs +0 -0
  157. {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
  158. {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
  159. {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
  160. {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
  161. {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
  162. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/source_bundle.rs +0 -0
  163. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/sourcemaps/inject.rs +0 -0
  164. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/sourcemaps.rs +0 -0
  165. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/system.rs +0 -0
  166. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/ui.rs +0 -0
  167. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/update.rs +0 -0
  168. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/value_parsers.rs +0 -0
  169. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/vcs.rs +0 -0
  170. {sentry_cli-3.2.0 → sentry_cli-3.2.2}/src/utils/xcode.rs +0 -0
@@ -2668,7 +2668,7 @@ dependencies = [
2668
2668
 
2669
2669
  [[package]]
2670
2670
  name = "sentry-cli"
2671
- version = "3.2.0"
2671
+ version = "3.2.2"
2672
2672
  dependencies = [
2673
2673
  "anyhow",
2674
2674
  "anylog",
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  build = "build.rs"
3
3
  name = "sentry-cli"
4
- version = "3.2.0"
4
+ version = "3.2.2"
5
5
  edition = "2021"
6
6
  rust-version = "1.91"
7
7
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.2.0
3
+ Version: 3.2.2
4
4
  Summary: A command line utility to work with Sentry.
5
5
  Home-page: https://github.com/getsentry/sentry-cli
6
6
  Author: Sentry
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.2.0
3
+ Version: 3.2.2
4
4
  Summary: A command line utility to work with Sentry.
5
5
  Home-page: https://github.com/getsentry/sentry-cli
6
6
  Author: Sentry
@@ -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
- #[error("request failed with retryable status code {}", .body.status)]
18
- pub(super) struct RetryError {
19
- body: ApiResponse,
20
- }
21
-
22
- impl RetryError {
23
- pub fn new(body: ApiResponse) -> Self {
24
- Self { body }
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, &url, auth)
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: &str,
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: &str,
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::new(rv));
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(err) => Ok(err.into_body()),
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::Args;
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
- #[derive(Args, Clone)]
46
- pub(crate) struct DartSymbolMapUploadArgs {
47
- #[arg(short = 'o', long = "org")]
48
- #[arg(help = "The organization ID or slug.")]
49
- pub(super) org: Option<String>,
50
-
51
- #[arg(short = 'p', long = "project")]
52
- #[arg(help = "The project ID or slug.")]
53
- pub(super) project: Option<String>,
54
-
55
- #[arg(value_name = "MAPPING")]
56
- #[arg(
57
- 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)."
58
- )]
59
- pub(super) mapping: String,
60
-
61
- #[arg(value_name = "DEBUG_FILE")]
62
- #[arg(
63
- help = "Path to the corresponding debug file to extract the Debug ID from. The file must contain exactly one Debug ID."
64
- )]
65
- pub(super) debug_file: String,
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(args: DartSymbolMapUploadArgs) -> Result<()> {
69
- let mapping_path = &args.mapping;
70
- let debug_file_path = &args.debug_file;
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 (default_org, default_project) = config.get_org_and_project_defaults();
119
- let org = args
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 else {
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