Skip to content

Commit f36c20c

Browse files
committed
CDRIVER-662 consistent errs from CRUD functions.
mongoc_collection_insert, mongoc_collection_update, and mongoc_collection_remove consistently use domain MONGOC_ERROR_BSON, code MONGOC_ERROR_BSON_INVALID if passed oversized BSON, and MONGOC_ERROR_COLLECTION for other errors. mongoc_bulk_operation_execute continues to use MONGOC_ERROR_COMMAND for all errors.
1 parent 28dad16 commit f36c20c

11 files changed

+289
-157
lines changed

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ New features and bug fixes:
4040
been available with "configure --enable-tracing".
4141
* Bugfix: "PossiblePrimary"-type replicas could be selected for reads
4242
* The random number generator used to select servers is now properly seeded.
43+
* mongoc_collection_insert, mongoc_collection_update, mongoc_collection_remove
44+
consistently use domain MONGOC_ERROR_BSON, code MONGOC_ERROR_BSON_INVALID
45+
if passed oversized BSON, and MONGOC_ERROR_COLLECTION for other errors.
46+
mongoc_bulk_operation_execute continues to use MONGOC_ERROR_COMMAND for
47+
all errors.
4348

4449
Removed configure flags:
4550
* --enable-experimental has been removed and all of its features

doc/mongoc_errors.page

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@
161161
<p><code>MONGOC_ERROR_BSON_INVALID</code></p>
162162
</td>
163163
<td>
164-
<p>Corrupt server reply, or you called <code xref="mongoc_collection_create_index">mongoc_collection_create_index</code> with invalid keys, or tried to insert or update with an invalid document.</p>
164+
<p>You passed an invalid or oversized BSON document as a parameter, or called <code xref="mongoc_collection_create_index">mongoc_collection_create_index</code> with invalid keys, or the server reply was corrupt.</p>
165165
</td>
166166
</tr>
167167
<tr>

src/mongoc/mongoc-bulk-operation.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */
679679
ret = _mongoc_write_result_complete (&bulk->result,
680680
bulk->client->error_api_version,
681681
bulk->write_concern,
682+
MONGOC_ERROR_COMMAND /* err domain */,
682683
reply,
683684
error);
684685
mongoc_server_stream_cleanup (server_stream);

src/mongoc/mongoc-collection.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,8 @@ mongoc_collection_insert_bulk (mongoc_collection_t *collection,
14601460
ret = _mongoc_write_result_complete (&result,
14611461
collection->client->error_api_version,
14621462
write_concern,
1463+
/* no error domain override */
1464+
(mongoc_error_domain_t) 0,
14631465
collection->gle,
14641466
error);
14651467

@@ -1547,6 +1549,8 @@ mongoc_collection_insert (mongoc_collection_t *collection,
15471549
ret = _mongoc_write_result_complete (&result,
15481550
collection->client->error_api_version,
15491551
write_concern,
1552+
/* no error domain override */
1553+
(mongoc_error_domain_t) 0,
15501554
collection->gle,
15511555
error);
15521556

@@ -1648,6 +1652,8 @@ mongoc_collection_update (mongoc_collection_t *collection,
16481652
ret = _mongoc_write_result_complete (&result,
16491653
collection->client->error_api_version,
16501654
write_concern,
1655+
/* no error domain override */
1656+
(mongoc_error_domain_t) 0,
16511657
collection->gle,
16521658
error);
16531659

@@ -1789,6 +1795,7 @@ mongoc_collection_remove (mongoc_collection_t *collection,
17891795
ret = _mongoc_write_result_complete (&result,
17901796
collection->client->error_api_version,
17911797
write_concern,
1798+
0 /* no error domain override */,
17921799
collection->gle,
17931800
error);
17941801

src/mongoc/mongoc-write-command-private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ void _mongoc_write_result_merge_legacy (mongoc_write_result_t *result,
140140
bool _mongoc_write_result_complete (mongoc_write_result_t *result,
141141
int32_t error_api_version,
142142
const mongoc_write_concern_t *wc,
143+
mongoc_error_domain_t err_domain_override,
143144
bson_t *reply,
144145
bson_error_t *error);
145146
void _mongoc_write_result_destroy (mongoc_write_result_t *result);

src/mongoc/mongoc-write-command.c

Lines changed: 81 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,46 @@ _mongoc_monitor_legacy_write_succeeded (mongoc_client_t *client,
583583
}
584584

585585

586+
/*
587+
*-------------------------------------------------------------------------
588+
*
589+
* too_large_error --
590+
*
591+
* Fill a bson_error_t and optional bson_t with error info after
592+
* receiving a document for bulk insert, update, or remove that is
593+
* larger than max_bson_size.
594+
*
595+
* "err_doc" should be NULL or an empty initialized bson_t.
596+
*
597+
* Returns:
598+
* None.
599+
*
600+
* Side effects:
601+
* "error" and optionally "err_doc" are filled out.
602+
*
603+
*-------------------------------------------------------------------------
604+
*/
605+
606+
static void
607+
too_large_error (bson_error_t *error,
608+
int32_t idx,
609+
int32_t len,
610+
int32_t max_bson_size,
611+
bson_t *err_doc)
612+
{
613+
bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID,
614+
"Document %u is too large for the cluster. "
615+
"Document is %u bytes, max is %d.",
616+
idx, len, max_bson_size);
617+
618+
if (err_doc) {
619+
BSON_APPEND_INT32 (err_doc, "index", idx);
620+
BSON_APPEND_UTF8 (err_doc, "err", error->message);
621+
BSON_APPEND_INT32 (err_doc, "code", MONGOC_ERROR_BSON_INVALID);
622+
}
623+
}
624+
625+
586626
static void
587627
_mongoc_write_command_delete_legacy (mongoc_write_command_t *command,
588628
mongoc_client_t *client,
@@ -595,6 +635,7 @@ _mongoc_write_command_delete_legacy (mongoc_write_command_t *command,
595635
bson_error_t *error)
596636
{
597637
int64_t started;
638+
int32_t max_bson_obj_size;
598639
const uint8_t *data;
599640
mongoc_rpc_t rpc;
600641
uint32_t request_id;
@@ -616,6 +657,8 @@ _mongoc_write_command_delete_legacy (mongoc_write_command_t *command,
616657

617658
started = bson_get_monotonic_time ();
618659

660+
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
661+
619662
r = bson_iter_init (&iter, command->documents);
620663
if (!r) {
621664
BSON_ASSERT (false);
@@ -647,6 +690,11 @@ _mongoc_write_command_delete_legacy (mongoc_write_command_t *command,
647690
bson_iter_document (&q_iter, &len, &data);
648691
BSON_ASSERT (data);
649692
BSON_ASSERT (len >= 5);
693+
if (len > max_bson_obj_size) {
694+
too_large_error (error, 0, len, max_bson_obj_size, NULL);
695+
result->failed = true;
696+
EXIT;
697+
}
650698

651699
request_id = ++client->cluster.request_id;
652700

@@ -709,49 +757,6 @@ _mongoc_write_command_delete_legacy (mongoc_write_command_t *command,
709757
}
710758

711759

712-
/*
713-
*-------------------------------------------------------------------------
714-
*
715-
* too_large_error --
716-
*
717-
* Fill a bson_error_t and optional bson_t with error info after
718-
* receiving a document for bulk insert, update, or remove that is
719-
* larger than max_bson_size.
720-
*
721-
* "err_doc" should be NULL or an empty initialized bson_t.
722-
*
723-
* Returns:
724-
* None.
725-
*
726-
* Side effects:
727-
* "error" and optionally "err_doc" are filled out.
728-
*
729-
*-------------------------------------------------------------------------
730-
*/
731-
732-
static void
733-
too_large_error (bson_error_t *error,
734-
int32_t idx,
735-
int32_t len,
736-
int32_t max_bson_size,
737-
bson_t *err_doc)
738-
{
739-
/* MongoDB 2.6 uses code 2 for "too large". TODO: see CDRIVER-644 */
740-
const int code = 2;
741-
742-
bson_set_error (error, MONGOC_ERROR_BSON, code,
743-
"Document %u is too large for the cluster. "
744-
"Document is %u bytes, max is %d.",
745-
idx, len, max_bson_size);
746-
747-
if (err_doc) {
748-
BSON_APPEND_INT32 (err_doc, "index", idx);
749-
BSON_APPEND_UTF8 (err_doc, "err", error->message);
750-
BSON_APPEND_INT32 (err_doc, "code", code);
751-
}
752-
}
753-
754-
755760
static void
756761
_mongoc_write_command_insert_legacy (mongoc_write_command_t *command,
757762
mongoc_client_t *client,
@@ -1007,6 +1012,7 @@ _mongoc_write_command_update_legacy (mongoc_write_command_t *command,
10071012
bson_error_t *error)
10081013
{
10091014
int64_t started;
1015+
int32_t max_bson_obj_size;
10101016
mongoc_rpc_t rpc;
10111017
uint32_t request_id = 0;
10121018
bson_iter_t iter, subiter, subsubiter;
@@ -1033,6 +1039,8 @@ _mongoc_write_command_update_legacy (mongoc_write_command_t *command,
10331039

10341040
started = bson_get_monotonic_time ();
10351041

1042+
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
1043+
10361044
bson_iter_init (&iter, command->documents);
10371045
while (bson_iter_next (&iter)) {
10381046
if (bson_iter_recurse (&iter, &subiter) &&
@@ -1085,11 +1093,23 @@ _mongoc_write_command_update_legacy (mongoc_write_command_t *command,
10851093
while (bson_iter_next (&subiter)) {
10861094
if (strcmp (bson_iter_key (&subiter), "u") == 0) {
10871095
bson_iter_document (&subiter, &len, &data);
1096+
if (len > max_bson_obj_size) {
1097+
too_large_error (error, 0, len, max_bson_obj_size, NULL);
1098+
result->failed = true;
1099+
EXIT;
1100+
}
1101+
10881102
rpc.update.update = data;
10891103
bson_init_static (&update, data, len);
10901104
has_update = true;
10911105
} else if (strcmp (bson_iter_key (&subiter), "q") == 0) {
10921106
bson_iter_document (&subiter, &len, &data);
1107+
if (len > max_bson_obj_size) {
1108+
too_large_error (error, 0, len, max_bson_obj_size, NULL);
1109+
result->failed = true;
1110+
EXIT;
1111+
}
1112+
10931113
rpc.update.selector = data;
10941114
bson_init_static (&selector, data, len);
10951115
has_selector = true;
@@ -1533,7 +1553,9 @@ _append_write_err_legacy (mongoc_write_result_t *result,
15331553

15341554
BSON_ASSERT (code > 0);
15351555

1536-
bson_set_error (&result->error, domain, (uint32_t) code, "%s", err);
1556+
if (!result->error.domain) {
1557+
bson_set_error (&result->error, domain, (uint32_t) code, "%s", err);
1558+
}
15371559

15381560
/* stop processing, if result->ordered */
15391561
result->failed = true;
@@ -1927,21 +1949,28 @@ _set_error_from_response (bson_t *bson_array,
19271949

19281950

19291951
bool
1930-
_mongoc_write_result_complete (mongoc_write_result_t *result, /* IN */
1931-
int32_t error_api_version, /* IN */
1932-
const mongoc_write_concern_t *wc, /* IN */
1933-
bson_t *bson, /* OUT */
1934-
bson_error_t *error) /* OUT */
1952+
_mongoc_write_result_complete (mongoc_write_result_t *result, /* IN */
1953+
int32_t error_api_version, /* IN */
1954+
const mongoc_write_concern_t *wc, /* IN */
1955+
mongoc_error_domain_t err_domain_override, /* IN */
1956+
bson_t *bson, /* OUT */
1957+
bson_error_t *error) /* OUT */
19351958
{
19361959
mongoc_error_domain_t domain;
19371960

19381961
ENTRY;
19391962

19401963
BSON_ASSERT (result);
19411964

1942-
domain = error_api_version >= MONGOC_ERROR_API_VERSION_2
1943-
? MONGOC_ERROR_SERVER
1944-
: MONGOC_ERROR_COMMAND;
1965+
if (error_api_version >= MONGOC_ERROR_API_VERSION_2) {
1966+
domain = MONGOC_ERROR_SERVER;
1967+
} else if (err_domain_override) {
1968+
domain = err_domain_override;
1969+
} else if (result->error.domain) {
1970+
domain = (mongoc_error_domain_t) result->error.domain;
1971+
} else {
1972+
domain = MONGOC_ERROR_COLLECTION;
1973+
}
19451974

19461975
if (bson && mongoc_write_concern_is_acknowledged (wc)) {
19471976
BSON_APPEND_INT32 (bson, "nInserted", result->nInserted);

0 commit comments

Comments
 (0)