Skip to content

Commit 6af81eb

Browse files
Reafctoring to use CosmosError instead of azure_core:Error (#4442)
## Summary Replaces the SDK's reliance on `azure_core::Error` for Cosmos failure reporting with a typed, diagnosable `Error` that's safe to construct at high rates in production. Every error returned from the driver or SDK now carries — without any downcasts or string parsing — the typed `CosmosStatus` (HTTP status + sub-status + categorical `Kind`), the parsed `CosmosResponseHeaders` (RU charge, activity id, session token, LSNs, …), the raw service response body, the shared `DiagnosticsContext` for the operation, and (where the production-safety gates allow) a captured stack backtrace. The previous `azure_core::Error` remains reachable via `std::error::Error::source()`. ## Motivation `azure_core::Error` exposes failure data behind an opaque enum and string messages, which forced callers into brittle pattern matches like `e.kind() == HttpResponse { status, .. }` and silently dropped Cosmos-specific fields (sub-status, RU charge, activity id, diagnostics) at the boundary. That made production triage of Cosmos failures (throttles, session retries, transport classifications, end-to-end timeouts) much harder than it needs to be. Java/.NET SDKs have shown that handing back rich error objects is a major usability win, but Java/.NET also illustrate the cost of getting this wrong: when stack-frame computation runs unbounded inside exception construction, a transient backend error storm can become a sustained client-side CPU pinhole. This PR adds the rich error surface **and** the production-safety machinery needed to keep that surface affordable under load. ## What changed ### New typed `Error` - **Driver** (`azure_data_cosmos_driver::error::Error`) is the canonical type. Single `Arc<ErrorInner>` so `Result<T, Error>` stays pointer-sized; `Clone` is a refcount bump. - **SDK** (`azure_data_cosmos::Error`) is a `#[repr(transparent)]` re-export of the driver type, plus the crate-wide `azure_data_cosmos::Result<T>` alias. - All SDK fallible APIs (clients, query/feed iterators, `into_model`/`single`/`items`, `FromStr` impls on `CosmosAccountEndpoint`/`ConnectionString`/`FeedRange`) now return `azure_data_cosmos::Result<T>` instead of `azure_core::Result<T>`. - Accessors: `status() -> CosmosStatus`, `status_code()`, `sub_status()`, `kind()`, `cosmos_headers() -> Option<ResponseHeaders>`, `diagnostics() -> Option<&Arc<DiagnosticsContext>>`, `response_body() -> Option<&[u8]>`, `backtrace() -> Option<&str>`, plus the usual `is_*` predicates on `CosmosStatus`. - Named `CosmosStatus` constants for well-known status/sub-status pairs (e.g. `CosmosStatus::TRANSPORT_GENERATED_503`, `READ_SESSION_NOT_AVAILABLE`, `RU_BUDGET_EXCEEDED`, `CROSS_PARTITION_QUERY_NOT_SERVABLE`) so call sites read as `assert_eq!(err.status(), CosmosStatus::CROSS_PARTITION_QUERY_NOT_SERVABLE)`. ### Boundary mapper `From<azure_core::Error>` classifies into the most specific `CosmosStatus` available — `HttpResponse` wins on its real wire status; otherwise the `azure_core::ErrorKind` plus a downcast walk of `.source()` (`reqwest`/`hyper`/`h2`/`io`) refines into synthetic sub-statuses (e.g. `TRANSPORT_DNS_FAILED`, `TRANSPORT_HTTP2_INCOMPATIBLE`, `AUTHENTICATION_TOKEN_ACQUISITION_FAILED`). The original `azure_core::Error` is preserved in the source chain. The driver transport layer carries typed `Error` end-to-end; nothing wraps a Cosmos error back into an `azure_core::Error`, so the typed payload is never lost on the wire. ### Stack backtrace capture — production-safe by construction Two-tier cost model with two independent rolling-1-second limiters: | Limiter | Bounds | Default | Env var / builder | | --- | --- | --- | --- | | **Capture throttle** | `Backtrace::capture()` — IP-only, microseconds | `1000 / s` | `AZURE_COSMOS_BACKTRACE_CAPTURES_PER_SECOND` / `with_max_error_backtrace_captures_per_second` | | **Resolution rate** | Symbolication on first `backtrace()` read — cache-missed frames only | `5 / s` | `AZURE_COSMOS_BACKTRACE_RESOLUTIONS_PER_SECOND` / `with_max_error_backtrace_resolutions_per_second` | Additional safety: - Resolved frames are cached process-wide by instruction pointer (soft cap 100K, swap-and-drop-outside-lock eviction). **Cache hits do not consume budget**, so once a hot stack is known it renders at full fidelity regardless of limiter state. - A per-window auto-disable kicks in on resolution-limiter denial: after one denial, no further capture in that window. The window clears on the next grant. - Partial backtraces are never produced — callers either get a fully-resolved render or `None`. - The first call's outcome is cached on the `Error` instance, so logging + telemetry + panic-message paths see the same answer. - Wrapping another Cosmos `Error` (e.g. transport-layer re-wrap) **inherits** the inner backtrace instead of capturing fresh, doubling the effective budget on retry-heavy paths. ### `Display` / `Debug` impls - `{e}` — bare message (matches `anyhow` / `azure_core` / `std::io` convention). - `{e:#}` — header (`[Kind] status/sub (name)`) + source chain (Display) + diagnostics block + backtrace. - `{e:?}` — header + source chain (Debug) + diagnostics. **No backtrace** to keep `tracing::error!(?e)` cheap. - `{e:#?}` — full report including backtrace; alternate flag cascades to source entries (`{src:#?}`) and to the `DiagnosticsContext` (`{diag:#?}`), so wrapped errors and diagnostics surface their pretty multi-line debug layout. ### Misc - `CosmosStatus::Display` / `Debug` now prefix the categorical `[Kind]` (e.g. `[Service] 429/3200 (RUBudgetExceeded)`). The `Deserialize` impl tolerates the `[Kind] ` prefix for JSON round-trip stability. - `Error::with_context(prefix)` for enriching mapper-classified errors with operation-specific context (single-allocation prepend, all typed fields preserved). - Removed `unsafe` from the SDK `ResponseHeaders` wrapper — `Error::cosmos_headers()` now returns an owned `Option<ResponseHeaders>` via a cheap clone (cold path) instead of the previous `repr(transparent)` reference transmute. ## Breaking changes (SDK) - All fallible SDK APIs now return `azure_data_cosmos::Result<T>`. Callers matching on `azure_core::ErrorKind` should switch to the typed accessors (`e.status_code()`, `e.sub_status()`, `e.status() == CosmosStatus::…`, `e.cosmos_headers()`, `e.diagnostics()`). The underlying `azure_core::Error` remains reachable via `std::error::Error::source()`. - `Error::cosmos_headers()` returns `Option<ResponseHeaders>` (by value, cloned) instead of `Option<&ResponseHeaders>`. - `CosmosStatus::Display` output now includes the `[Kind]` prefix; any diagnostics consumers that parsed the previous bare `"429/3200 (…)"` shape need to either accept the new format or use the typed accessors. ## Testing - `cargo test -p azure_data_cosmos_driver --lib --all-features` — **1670+ tests green** (added coverage for backtrace limiter behavior, source-chain inheritance, `Display`/`Debug` format variants and alternate-flag cascade, named-constant comparisons, sub-status serialization with and without well-known names, JSON snapshot updates for the new status format). - Cross-crate build clean across `azure_data_cosmos`, `azure_data_cosmos_driver`, `azure_data_cosmos_perf`, `azure_data_cosmos_benchmarks`. - Doctests updated to the new SDK `Result<()>` alias. ## Notes for reviewers - The throttle defaults (1000 captures/s, 5 resolutions/s) are deliberately conservative; they're tunable per-runtime and per-env. The README in `azure_data_cosmos_driver` has a "when to adjust which" section. - The boundary mapper is intentionally a one-way conversion. If you see a code path that round-trips through `azure_core::Error`, please flag it — that's a regression that would lose the typed payload. - `Error::client` / `Error::serialization` / `Error::configuration` are `#[doc(hidden)] pub` so the SDK wrapper crate can construct typed errors; they are not part of the public surface. ## Backtrace machinery benchmarks `cargo bench -p azure_data_cosmos_benchmarks --bench backtrace_capture` Reviewed against the production-readiness changes (opt-in capture, two-limiter model, source-error backtrace inheritance, `OnceLock` per-instance render cache). ### Changes to the bench harness - Added `capture/cosmos/inherit_from_source` to cover the re-wrap path on `CosmosErrorBuilder::with_arc_source(cosmos_err)`. This path skips a fresh stack walk and inherits the source's `Backtrace`, which is a key production optimization but was previously unmeasured. - Annotated `capture/cosmos/throttle_denied` to make explicit that it also represents the **default production state** (capture is opt-in; with `RUST_BACKTRACE` unset the same fast-denial path runs on every construction). - Removed a redundant second `prime_resolution_cache()` call (left over from when the limiter capacity was 1) — the unbounded limiter only needs one prime pass. - Updated the module-level docs table accordingly. ### Results (Windows, release, 100 samples per group) | Group / variant | Mean | Notes | |---|---|---| | `capture/cosmos/unbounded` | **1.36 µs** | Cold capture path, throttle wide open — instruction-pointer walk only. | | `capture/cosmos/throttle_denied` | **1.82 ns** | Single `AtomicU64` CAS denial. Also the default-off production cost when `RUST_BACKTRACE` is unset. **~750× cheaper than `unbounded`**, ~915× cheaper than `std::backtrace::Backtrace::force_capture`. | | `capture/cosmos/inherit_from_source` | **1.68 µs** | Full `CosmosErrorBuilder` build (alloc + status + message + `Arc<source>` clone) that inherits the source's backtrace — i.e. *does not* re-capture. Effectively equal to `std::force_capture` alone, so the entire builder overhead disappears into the cost of one stack walk that we are deliberately skipping. | | `capture/std/force_capture` | **1.68 µs** | `std::backtrace::Backtrace::force_capture()` baseline. | | `render/cosmos/cached` | **20.6 ns** | `OnceLock` hit on the per-instance render cache — the steady-state cost of every `CosmosError::backtrace()` call after the first one. **~735× cheaper than `std::backtrace::to_string`**. | | `render/cosmos/fresh_warm_cache` | **5.76 µs** | Fresh `Backtrace` per iter, process-global IP-keyed frame cache hot — pays cache lookup only, no symbol resolution, no budget consumption. | | `render/cosmos/fresh_cold_resolution_denied` | **3.21 µs** | Fresh `Backtrace` per iter with the resolution limiter exhausted — proves the denial fast-path is cheaper than even a fully cached resolution. Validates the "no partial backtraces" guarantee. | | `render/std/to_string` | **15.2 µs** | `std::backtrace::Backtrace::to_string()` baseline — std has no per-instance cache; every call re-walks debug info. | ### Conclusions 1. **Default off is free.** The opt-in design pays for itself: 1.82 ns per error construction when `RUST_BACKTRACE` is unset (a single CAS), versus 1.36 µs for the captured path. Default-off error storms cost the same as an atomic decrement. 2. **Source-error inheritance is real.** Re-wrapping a `CosmosError` adds the cost of the builder plumbing only — no second stack walk — so the pipeline's re-wrap sites (transport → service, status promotion, etc.) do not multiply backtrace cost across nested errors. 3. **Per-instance render cache is the right tradeoff.** A cached `CosmosError::backtrace()` call returns in ~21 ns, versus 15 µs for `std::backtrace` — a structural difference of ~700×, mattering on any path that formats the same error multiple times (e.g. `tracing::error!("{e}")` + `Result::unwrap` panic message). 4. **Resolution-limiter denial is cheaper than a cache-hit render.** A denied resolution (~3.2 µs) costs less than rendering the same backtrace through the warm frame cache (~5.8 µs), so the "deny rather than partially render" rule cannot regress under capacity pressure. All benches and the production code build clean (`-D warnings`, all features).
1 parent 1999560 commit 6af81eb

146 files changed

Lines changed: 9028 additions & 2680 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ async-stream = { version = "0.3.6" }
8888
async-trait = "0.1"
8989
base64 = "0.22"
9090
arc-swap = "1.7"
91+
backtrace = "0.3"
9192
bytes = "1.11.1"
9293
cargo_metadata = "0.23.1"
9394
clap = { version = "4.5.58", features = ["derive"] }

sdk/cosmos/.cspell.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"fabianm",
5858
"failback",
5959
"failovers",
60+
"fanout",
6061
"FILETIME",
6162
"flamegraph",
6263
"fmix",
@@ -154,6 +155,7 @@
154155
"southindia",
155156
"sproc",
156157
"sprocs",
158+
"stdlib",
157159
"subsec",
158160
"substatus",
159161
"supportedcapabilities",

sdk/cosmos/.github/skills/cosmos-design-struct/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ If a separate builder type is used, follow these conventions:
226226
1. Name it `<Type>Builder`.
227227
2. Keep builder fields private.
228228
3. Provide `with_*` setters for optional fields.
229-
4. Provide terminal `build(self, ...) -> <Type>` (or `azure_core::Result<Type>` when fallible).
229+
4. Provide terminal `build(self, ...) -> <Type>` (or `crate::error::Result<Type>` / `azure_data_cosmos::Result<Type>` when fallible).
230230
5. Keep required fields on `build(...)`, not as optional builder state.
231231
6. Add `<Type>::builder(... required args ...) -> <Type>Builder` to initialize the builder type.
232232

sdk/cosmos/AGENTS.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl MyType {
4545

4646
// ✅ GOOD: Implement the standard trait
4747
impl std::str::FromStr for MyType {
48-
type Err = azure_core::Error;
48+
type Err = azure_data_cosmos::Error;
4949
fn from_str(s: &str) -> Result<Self, Self::Err> { /* ... */ }
5050
}
5151

@@ -66,7 +66,7 @@ If you need a non-fallible parse internally, create a **private** helper method
6666

6767
#### Error Handling
6868

69-
- Use `azure_core::Result<T>` for all fallible operations
69+
- Use `azure_data_cosmos::Result<T>` (SDK) or `azure_data_cosmos_driver::error::Result<T>` (driver) for all fallible operations — both alias `Result<T, crate::Error>` over the typed Cosmos error.
7070
- **Prefer returning `Result::Err` over panicking** in public methods whose inputs could originate from user-constructed types (even indirectly). Callers can then decide whether to propagate, log, or handle — rather than crashing their application. Use `assert!`/`panic!` only for true invariant violations that indicate programmer error in internal code.
7171
- Cosmos-specific errors should provide:
7272
- HTTP status code
@@ -190,7 +190,7 @@ pub async fn create_item<T: Serialize>(
190190
&self,
191191
item: &T,
192192
options: &CreateItemOptions,
193-
) -> azure_core::Result<ItemResponse<T>>
193+
) -> azure_data_cosmos::Result<ItemResponse<T>>
194194
where
195195
T: for<'de> Deserialize<'de>,
196196
{
@@ -355,7 +355,7 @@ pub mod builders {
355355
endpoint: impl Into<String>,
356356
credential: impl TokenCredential,
357357
options: DriverOptions,
358-
) -> azure_core::Result<Driver> {
358+
) -> azure_data_cosmos_driver::error::Result<Driver> {
359359
// ... construction logic
360360
}
361361
}

sdk/cosmos/azure_data_cosmos/CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
### Features Added
66

7-
- Added `RegionStrategy::PreferredRegions` to allow specifying a fixed region preference order for failover, hedging, and retry. ([#4485](https://github.com/Azure/azure-sdk-for-rust/pull/4485))
7+
- `CosmosError` can capture a stack backtrace on construction. Capture is opt-in (off by default; on when `RUST_BACKTRACE` is set or when explicit capacities are supplied) and protected against error storms by two configurable per-second limiters on the runtime builder. ([#4442](https://github.com/Azure/azure-sdk-for-rust/pull/4442))
8+
- Introduced `azure_data_cosmos::CosmosError` and the crate-wide `azure_data_cosmos::Result<T>` alias, surfacing typed `CosmosStatus` (with predicate accessors like `is_not_found()` / `is_throttled()` / `is_transient()`), the originating `CosmosResponse`, and the operation `DiagnosticsContext` on every failure. `From<CosmosError> for azure_core::Error` is provided so callers using `?` against `azure_core::Error` continue to compose. ([#4442](https://github.com/Azure/azure-sdk-for-rust/pull/4442))
9+
- Added `RoutingStrategy::PreferredRegions` to allow specifying a fixed region preference order for failover, hedging, and retry. ([#4485](https://github.com/Azure/azure-sdk-for-rust/pull/4485))
810
- Standardized every client-method options type with a public `operation: OperationOptions` field and `with_operation_options(OperationOptions) -> Self` setter, so any per-request `OperationOptions` setting can be configured via any options type. The following options types previously had no way to attach `OperationOptions` and now do: `ReadContainerOptions`, `ReadDatabaseOptions`, `ReplaceContainerOptions`, `CreateContainerOptions`, `CreateDatabaseOptions`, `DeleteContainerOptions`, `DeleteDatabaseOptions`, `QueryContainersOptions`, `QueryDatabasesOptions`, `ThroughputOptions`, `ReadFeedRangesOptions`. For `CreateContainerOptions` / `CreateDatabaseOptions` / `ReplaceContainerOptions`, the SDK still forces `content_response_on_write = Enabled` on the resolved options because control-plane mutations require the response body. `ReadFeedRangesOptions::operation` is currently inert (the underlying routing-map cache does not go through the operation pipeline) but is added for shape consistency with the other options types.
911
- Added `new()` constructors and `with_x` consuming setters to multi-required-field model types so callers can build them declaratively without struct-literal syntax (which is now blocked by `#[non_exhaustive]`): `VectorEmbedding::new(path, data_type, dimensions, distance_function)` + `with_path` / `with_data_type` / `with_dimensions` / `with_distance_function`; `ConflictResolutionPolicy::new(mode)` + `with_resolution_path` / `with_resolution_procedure`; `SpatialIndex::new(path)` + `with_type` (singular pusher onto `types`); `CompositeIndexProperty::new(path, order)` + `with_path` / `with_order`; `VectorIndex::new(path, index_type)` + `with_path` / `with_index_type`. These types do **not** implement `Default` — their constructors require values that have no meaningful default.
1012
- Derived `Default` on `VectorEmbeddingPolicy`, `UniqueKeyPolicy`, `UniqueKey`, `PropertyPath`, and `CompositeIndex`, and added singular `with_x` pushers / setters: `VectorEmbeddingPolicy::with_embedding`, `UniqueKeyPolicy::with_unique_key`, `UniqueKey::with_path`, `PropertyPath::with_path`, and `CompositeIndex::with_property`. This matches the existing `IndexingPolicy::with_included_path` style and lets callers build these policies declaratively without constructing intermediate `Vec`s.
@@ -17,6 +19,7 @@
1719

1820
### Breaking Changes
1921

22+
- All fallible public APIs now return `azure_data_cosmos::Result<T>` (= `Result<T, CosmosError>`) instead of `azure_core::Result<T>`, and the error type was renamed `Error``CosmosError` (with `CosmosErrorBuilder` for construction). Categorization moved from a `Kind` enum to predicates on `CosmosStatus` (`is_not_found()`, `is_throttled()`, `is_transient()`, …); the underlying `azure_core::Error` is still reachable via `std::error::Error::source()`. ([#4442](https://github.com/Azure/azure-sdk-for-rust/pull/4442))
2023
- Moved `QueryOptions::max_item_count` and `QueryOptions::continuation_token` into the new `QueryOptions::feed: FeedOptions` field. Callers that read or assign these fields directly should switch to `options.feed.max_item_count` / `options.feed.continuation_token`. The `with_max_item_count` / `with_continuation_token` convenience setters on `QueryOptions` continue to work unchanged.
2124
- `ThroughputProperties` is now `#[non_exhaustive]` and no longer derives `Default`. The `Default` impl produced a meaningless wire payload (no manual throughput and no autoscale settings, which would send an empty offer body). Callers should use `ThroughputProperties::manual(throughput)` or `ThroughputProperties::autoscale(starting_maximum_throughput, increment_percent)` instead.
2225
- Marked the following public model enums and response wrappers as `#[non_exhaustive]` to allow future variants/fields to be added without further breaking changes: `VectorDataType`, `VectorDistanceFunction`, `ConflictResolutionMode`, `IndexingMode`, `SpatialType`, `CompositeIndexOrder`, `VectorIndexType`, `BatchResponse`, `ItemResponse`, `ResourceResponse<T>`, `ResponseBody`, `ResponseHeaders`, `PartitionKeyVersion` and `CosmosStatus`. Callers must use `..` wildcard arms in `match`es over these enums and cannot construct these structs via struct-literal syntax (the SDK already provides constructors / setters for the constructable types).
@@ -43,7 +46,6 @@
4346
- Removed `azure_data_cosmos::constants::SubStatusCode` and its `new`/`value`/`from_header_value`/`From`/`Display`/`Debug` API. The SDK no longer maintains a parallel sub-status-code type.
4447
- The `User-Agent` header on every outgoing Cosmos DB request now identifies the wrapping SDK in addition to the driver. The new format is `azsdk-rust-cosmos/<sdk-version> azsdk-rust-cosmos-driver/<driver-version> <os>/<arch> rustc/<ver> [suffix]`, where `<sdk-version>` is this crate's version. This is wired automatically via the new `CosmosDriverRuntimeBuilder::with_wrapping_sdk_identifier` API in the driver, and lets telemetry distinguish callers using `azure_data_cosmos` from callers driving `azure_data_cosmos_driver` directly. No API surface in `azure_data_cosmos` changes. ([#4465](https://github.com/Azure/azure-sdk-for-rust/pull/4465))
4548
- The `azure_data_cosmos::constants` module is no longer public. It only contained internal HTTP-header-name constants used by the SDK's own pipeline plumbing; nothing from it was intended for consumer use. The one previously-exposed public item (`SubStatusCode`) is re-exported from the crate root — see the bullet above.
46-
>>>>>>> Conflict 1 of 1 ends
4749

4850
### Bugs Fixed
4951

sdk/cosmos/azure_data_cosmos/docs/in-memory-emulator-spec.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -933,10 +933,11 @@ ContainerConfig::new()
933933

934934
`with_partition_count` and `with_throughput` are infallible setters; all
935935
validation happens in a single `build()` step that returns
936-
`azure_core::Result<ContainerConfig>`. Use `build()?` inside a function
937-
that returns `azure_core::Result<_>` (or `unwrap()` in tests).
936+
`azure_data_cosmos_driver::error::Result<ContainerConfig>`. Use `build()?`
937+
inside a function that returns a compatible `Result<_, _>` (or `unwrap()`
938+
in tests).
938939

939-
Minimum provisioned throughput is 400 RU/s; values below this and a partition count of `0` are rejected with an `azure_core::Error` from `build()`.
940+
Minimum provisioned throughput is 400 RU/s; values below this and a partition count of `0` are rejected with a `Client`-kind `azure_data_cosmos_driver::error::Error` from `build()`.
940941

941942
### Per-Partition Tracking
942943

sdk/cosmos/azure_data_cosmos/examples/cosmos/delete.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
use std::error::Error;
55

6-
use azure_core::http::StatusCode;
76
use azure_data_cosmos::CosmosClient;
87
use clap::{Args, Subcommand};
98

@@ -65,7 +64,7 @@ impl DeleteCommand {
6564
.delete_item(partition_key, &item_id, None)
6665
.await;
6766
match response {
68-
Err(e) if e.http_status() == Some(StatusCode::NotFound) => {
67+
Err(e) if e.status().is_not_found() => {
6968
println!("Item not found!")
7069
}
7170
Ok(_) => println!("Item deleted"),

sdk/cosmos/azure_data_cosmos/examples/cosmos/read.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
use std::error::Error;
55

6-
use azure_core::http::StatusCode;
76
use azure_data_cosmos::CosmosClient;
87
use clap::{Args, Subcommand};
98

@@ -60,7 +59,7 @@ impl ReadCommand {
6059
.read_item(&partition_key, &item_id, None)
6160
.await;
6261
match response {
63-
Err(e) if e.http_status() == Some(StatusCode::NotFound) => {
62+
Err(e) if e.status().is_not_found() => {
6463
println!("Item not found!")
6564
}
6665
Ok(r) => {

sdk/cosmos/azure_data_cosmos/examples/cosmos/replace.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
use std::error::Error;
55

6-
use azure_core::http::StatusCode;
76
use azure_data_cosmos::{
87
ContentResponseOnWrite, CosmosClient, ItemWriteOptions, OperationOptions, PartitionKey,
98
};
@@ -91,7 +90,7 @@ impl ReplaceCommand {
9190
.replace_item(pk, &item_id, item, options)
9291
.await;
9392
match response {
94-
Err(e) if e.http_status() == Some(StatusCode::NotFound) => {
93+
Err(e) if e.status().is_not_found() => {
9594
println!("Item not found!")
9695
}
9796
Ok(r) => {

0 commit comments

Comments
 (0)