diff --git a/src/libmongoc/src/mongoc/mongoc-error-private.h b/src/libmongoc/src/mongoc/mongoc-error-private.h index fd0f2b10b65..41025a3e52f 100644 --- a/src/libmongoc/src/mongoc/mongoc-error-private.h +++ b/src/libmongoc/src/mongoc/mongoc-error-private.h @@ -89,4 +89,8 @@ _mongoc_error_is_server (const bson_error_t *error); bool _mongoc_error_is_auth (const bson_error_t *error); +/* Try to append `s` to `error`. Truncates `s` if `error` is out of space. */ +void +_mongoc_error_append (bson_error_t *error, const char *s); + BSON_END_DECLS diff --git a/src/libmongoc/src/mongoc/mongoc-error.c b/src/libmongoc/src/mongoc/mongoc-error.c index a9b9501eaf8..00338718861 100644 --- a/src/libmongoc/src/mongoc/mongoc-error.c +++ b/src/libmongoc/src/mongoc/mongoc-error.c @@ -311,3 +311,12 @@ _mongoc_error_is_auth (const bson_error_t *error) return error->domain == MONGOC_ERROR_CLIENT && error->code == MONGOC_ERROR_CLIENT_AUTHENTICATE; } + +void +_mongoc_error_append (bson_error_t *error, const char *s) +{ + BSON_ASSERT (error); + const size_t error_len = strlen (error->message); + const size_t remaining = sizeof (error->message) - error_len; + bson_strncpy (error->message + error_len, s, remaining); +} diff --git a/src/libmongoc/src/mongoc/mongoc-topology.c b/src/libmongoc/src/mongoc/mongoc-topology.c index b1a5a4ee456..61b23bd3fd2 100644 --- a/src/libmongoc/src/mongoc/mongoc-topology.c +++ b/src/libmongoc/src/mongoc/mongoc-topology.c @@ -1098,6 +1098,9 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, uint32_t server_id; mc_shared_tpld td = mc_tpld_take_ref (topology); + bson_string_t *topology_type = bson_string_new (". Topology type: "); + bson_string_append (topology_type, mongoc_topology_description_type (td.ptr)); + /* These names come from the Server Selection Spec pseudocode */ int64_t loop_start; /* when we entered this function */ int64_t loop_end; /* when we last completed a loop (single-threaded) */ @@ -1153,10 +1156,7 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, if (scan_ready > expire_at && !try_once) { /* selection timeout will expire before min heartbeat passes */ - _mongoc_server_selection_error ("No suitable servers found: " - "`serverselectiontimeoutms` timed out", - &scanner_error, - error); + _mongoc_server_selection_error (timeout_msg, &scanner_error, error); server_id = 0; goto done; @@ -1301,6 +1301,10 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology, } done: + if (error) { + _mongoc_error_append (error, topology_type->str); + } + bson_string_free (topology_type, true); mc_tpld_drop_ref (&td); return server_id; } diff --git a/src/libmongoc/tests/test-mongoc-server-selection-errors.c b/src/libmongoc/tests/test-mongoc-server-selection-errors.c index c62971cce36..f7793fe90f5 100644 --- a/src/libmongoc/tests/test-mongoc-server-selection-errors.c +++ b/src/libmongoc/tests/test-mongoc-server-selection-errors.c @@ -81,7 +81,8 @@ test_server_selection_error_dns_direct_single (void) { server_selection_error_dns ("mongodb://example-localhost.invalid:27017/", "No suitable servers found (`serverSelectionTryOnce` set): " - "[Fake error for 'example-localhost.invalid']", + "[Fake error for 'example-localhost.invalid']" + ". Topology type: Single", false, false); } @@ -93,7 +94,8 @@ test_server_selection_error_dns_direct_pooled (void *ctx) server_selection_error_dns ("mongodb://example-localhost.invalid:27017/", "No suitable servers found: `serverSelectionTimeoutMS` expired: " - "[Fake error for 'example-localhost.invalid']", + "[Fake error for 'example-localhost.invalid']" + ". Topology type: Single", false, true); } @@ -105,7 +107,8 @@ test_server_selection_error_dns_multi_fail_single (void) "example-localhost.invalid:27017,other-example-localhost.invalid:27017/", "No suitable servers found (`serverSelectionTryOnce` set):" " [Fake error for 'example-localhost.invalid']" - " [Fake error for 'other-example-localhost.invalid']", + " [Fake error for 'other-example-localhost.invalid']" + ". Topology type: Unknown", false, false); } @@ -119,7 +122,8 @@ test_server_selection_error_dns_multi_fail_pooled (void *ctx) "example-localhost.invalid:27017,other-example-localhost.invalid:27017/", "No suitable servers found: `serverSelectionTimeoutMS` expired:" " [Fake error for 'example-localhost.invalid']" - " [Fake error for 'other-example-localhost.invalid']", + " [Fake error for 'other-example-localhost.invalid']" + ". Topology type: Unknown", false, true); }