Skip to content

Commit 9a2a113

Browse files
Utkarsh Mehtautkmehta
authored andcommitted
RUST-370 Ensuring that the WriteConcernError errInfo object is propagated
1 parent a497db1 commit 9a2a113

File tree

5 files changed

+105
-5
lines changed

5 files changed

+105
-5
lines changed

src/error.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use lazy_static::lazy_static;
77
use serde::Deserialize;
88
use time::OutOfRangeError;
99

10-
use crate::options::StreamAddress;
10+
use crate::{bson::Document, options::StreamAddress};
1111

1212
lazy_static! {
1313
static ref RECOVERING_CODES: Vec<i32> = vec![11600, 11602, 13436, 189, 91];
@@ -381,6 +381,10 @@ pub struct WriteConcernError {
381381
/// A description of the error that occurred.
382382
#[serde(rename = "errmsg")]
383383
pub message: String,
384+
385+
/// A document identifying the write concern setting related to the error.
386+
#[serde(rename = "errInfo")]
387+
pub details: Option<Document>,
384388
}
385389

386390
/// An error that occurred during a write operation that wasn't due to being unable to satisfy a

src/operation/delete/test.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,14 @@ async fn handle_write_concern_failure() {
167167
"writeConcernError": {
168168
"code": 456,
169169
"codeName": "wcError",
170-
"errmsg": "some message"
170+
"errmsg": "some message",
171+
"errInfo": {
172+
"writeConcern": {
173+
"w": 2,
174+
"wtimeout": 0,
175+
"provenance": "clientSupplied"
176+
}
177+
}
171178
}
172179
});
173180

@@ -180,6 +187,11 @@ async fn handle_write_concern_failure() {
180187
code: 456,
181188
code_name: "wcError".to_string(),
182189
message: "some message".to_string(),
190+
details: Some(doc! { "writeConcern": {
191+
"w": 2,
192+
"wtimeout": 0,
193+
"provenance": "clientSupplied"
194+
} }),
183195
};
184196
assert_eq!(wc_error, &expected_wc_err);
185197
}

src/operation/insert/test.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,14 @@ async fn handle_write_failure() {
179179
"writeConcernError": {
180180
"code": 123,
181181
"codeName": "woohoo",
182-
"errmsg": "error message"
182+
"errmsg": "error message",
183+
"errInfo": {
184+
"writeConcern": {
185+
"w": 2,
186+
"wtimeout": 0,
187+
"provenance": "clientSupplied"
188+
}
189+
}
183190
}
184191
});
185192

@@ -203,6 +210,11 @@ async fn handle_write_failure() {
203210
code: 123,
204211
code_name: "woohoo".to_string(),
205212
message: "error message".to_string(),
213+
details: Some(doc! { "writeConcern": {
214+
"w": 2,
215+
"wtimeout": 0,
216+
"provenance": "clientSupplied"
217+
} }),
206218
};
207219
assert_eq!(write_concern_error, expected_wc_err);
208220
}

src/operation/update/test.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,14 @@ async fn handle_write_concern_failure() {
252252
"writeConcernError": {
253253
"code": 456,
254254
"codeName": "wcError",
255-
"errmsg": "some message"
255+
"errmsg": "some message",
256+
"errInfo": {
257+
"writeConcern": {
258+
"w": 2,
259+
"wtimeout": 0,
260+
"provenance": "clientSupplied"
261+
}
262+
}
256263
}
257264
});
258265

@@ -265,6 +272,11 @@ async fn handle_write_concern_failure() {
265272
code: 456,
266273
code_name: "wcError".to_string(),
267274
message: "some message".to_string(),
275+
details: Some(doc! { "writeConcern": {
276+
"w": 2,
277+
"wtimeout": 0,
278+
"provenance": "clientSupplied"
279+
} }),
268280
};
269281
assert_eq!(wc_error, &expected_wc_err);
270282
}

src/test/coll.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use semver::VersionReq;
66

77
use crate::{
88
bson::{doc, Bson, Document},
9-
error::{ErrorKind, Result},
9+
error::{ErrorKind, Result, WriteFailure},
1010
event::command::CommandStartedEvent,
1111
options::{
1212
AggregateOptions,
@@ -25,6 +25,66 @@ use crate::{
2525
RUNTIME,
2626
};
2727

28+
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
29+
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
30+
#[function_name::named]
31+
async fn insert_err_details() {
32+
let _guard = LOCK.run_exclusively().await;
33+
34+
let client = TestClient::new().await;
35+
let coll = client
36+
.init_db_and_coll(function_name!(), function_name!())
37+
.await;
38+
if client.server_version_lt(4, 0) || !client.is_replica_set() {
39+
return;
40+
}
41+
client
42+
.database("admin")
43+
.run_command(
44+
doc! {
45+
"configureFailPoint": "failCommand",
46+
"data": {
47+
"failCommands": ["insert"],
48+
"writeConcernError": {
49+
"code": 100,
50+
"codeName": "UnsatisfiableWriteConcern",
51+
"errmsg": "Not enough data-bearing nodes",
52+
"errInfo": {
53+
"writeConcern": {
54+
"w": 2,
55+
"wtimeout": 0,
56+
"provenance": "clientSupplied"
57+
}
58+
}
59+
}
60+
},
61+
"mode": { "times": 1 }
62+
},
63+
None,
64+
)
65+
.await
66+
.unwrap();
67+
68+
let wc_error_result = coll.insert_one(doc! { "test": 1 }, None).await;
69+
match *wc_error_result.unwrap_err().kind {
70+
ErrorKind::WriteError(WriteFailure::WriteConcernError(ref wc_error)) => {
71+
match &wc_error.details {
72+
Some(doc) => {
73+
let result = doc.get_document("writeConcern");
74+
match result {
75+
Ok(write_concern_doc) => {
76+
assert_eq!(write_concern_doc.contains_key("provenance"), true);
77+
}
78+
Err(e) => panic!("{:?}", e),
79+
}
80+
}
81+
None => panic!("expected details field"),
82+
}
83+
}
84+
ref e => panic!("expected write concern error, got {:?}", e),
85+
}
86+
}
87+
2888
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
2989
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
3090
#[function_name::named]

0 commit comments

Comments
 (0)