Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions php_phongo.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ static int phongo_exception_append_error_labels(zval* labels, const bson_iter_t*
bson_iter_t error_labels;
uint32_t label_count = 0;

bson_iter_recurse(iter, &error_labels);
if (!BSON_ITER_HOLDS_ARRAY(iter) || !bson_iter_recurse(iter, &error_labels)) {
return label_count;
}

while (bson_iter_next(&error_labels)) {
if (BSON_ITER_HOLDS_UTF8(&error_labels)) {
const char* error_label;
Expand All @@ -217,7 +220,7 @@ static int phongo_exception_append_error_labels(zval* labels, const bson_iter_t*

static void phongo_exception_add_error_labels(const bson_t* reply)
{
bson_iter_t iter;
bson_iter_t iter, child;
zval labels;
uint32_t label_count = 0;

Expand All @@ -231,12 +234,20 @@ static void phongo_exception_add_error_labels(const bson_t* reply)
label_count += phongo_exception_append_error_labels(&labels, &iter);
}

if (bson_iter_init_find(&iter, reply, "writeConcernError")) {
bson_iter_t write_concern_error_iter;
if (bson_iter_init_find(&iter, reply, "writeConcernError") && BSON_ITER_HOLDS_DOCUMENT(&iter) &&
bson_iter_recurse(&iter, &child) && bson_iter_find(&child, "errorLabels")) {
label_count += phongo_exception_append_error_labels(&labels, &child);
}

/* mongoc_write_result_t always reports writeConcernErrors in an array, so
* we must iterate this to collect WCE labels for BulkWrite replies. */
if (bson_iter_init_find(&iter, reply, "writeConcernErrors") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) {
bson_iter_t wce;

bson_iter_recurse(&iter, &write_concern_error_iter);
if (bson_iter_find(&write_concern_error_iter, "errorLabels")) {
label_count += phongo_exception_append_error_labels(&labels, &write_concern_error_iter);
while (bson_iter_next(&child)) {
if (BSON_ITER_HOLDS_DOCUMENT(&child) && bson_iter_recurse(&child, &wce) && bson_iter_find(&wce, "errorLabels")) {
label_count += phongo_exception_append_error_labels(&labels, &wce);
}
}
}

Expand Down
41 changes: 41 additions & 0 deletions tests/exception/bulkwriteexception-haserrorlabel-002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
MongoDB\Driver\Exception\BulkWriteException::hasErrorLabel() with writeConcernError
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
<?php skip_if_no_failcommand_failpoint(); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";

// Disable retryWrites since we want to check for a RetryableWriteError error label
$manager = new MongoDB\Driver\Manager(URI, ['retryWrites' => false]);

// Select a specific server for future operations to avoid mongos switching in sharded clusters
$server = $manager->selectServer(new \MongoDB\Driver\ReadPreference('primary'));

configureTargetedFailPoint($server, 'failCommand', [ 'times' => 1 ], [
'failCommands' => ['insert'],
'writeConcernError' => [
'code' => 91,
'errmsg' => 'Replication is being shut down',
'errorLabels' => ['RetryableWriteError'],
],
]);

$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert(['x' => 1]);

try {
$server->executeBulkWrite(NS, $bulk);
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
var_dump($e->hasErrorLabel('RetryableWriteError'));
}

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
bool(true)
===DONE===