diff --git a/src/MongoDB/Exception/ConnectionTimeoutException.c b/src/MongoDB/Exception/ConnectionTimeoutException.c index 136c8e093..a9d866946 100644 --- a/src/MongoDB/Exception/ConnectionTimeoutException.c +++ b/src/MongoDB/Exception/ConnectionTimeoutException.c @@ -17,10 +17,25 @@ #include #include "php_phongo.h" +#include "phongo_error.h" #include "ConnectionTimeoutException_arginfo.h" zend_class_entry* php_phongo_connectiontimeoutexception_ce; +/* Returns the WriteResult from the failed write operation. */ +static PHP_METHOD(MongoDB_Driver_Exception_ConnectionTimeoutException, getWriteResult) +{ + zval* writeresult; + zval rv; + + PHONGO_PARSE_PARAMETERS_NONE(); + + writeresult = zend_read_property(php_phongo_bulkwriteexception_ce, Z_OBJ_P(getThis()), ZEND_STRL("writeResult"), 0, &rv); + + RETURN_ZVAL(writeresult, 1, 0); +} + + void php_phongo_connectiontimeoutexception_init_ce(INIT_FUNC_ARGS) { php_phongo_connectiontimeoutexception_ce = register_class_MongoDB_Driver_Exception_ConnectionTimeoutException(php_phongo_connectionexception_ce); diff --git a/src/MongoDB/Exception/ConnectionTimeoutException.stub.php b/src/MongoDB/Exception/ConnectionTimeoutException.stub.php index aef91e752..7d9b24a40 100644 --- a/src/MongoDB/Exception/ConnectionTimeoutException.stub.php +++ b/src/MongoDB/Exception/ConnectionTimeoutException.stub.php @@ -9,4 +9,8 @@ final class ConnectionTimeoutException extends ConnectionException { + /** @var \MongoDB\Driver\WriteResult */ + protected $writeResult; + + final public function getWriteResult(): \MongoDB\Driver\WriteResult {} } diff --git a/src/MongoDB/Exception/ConnectionTimeoutException_arginfo.h b/src/MongoDB/Exception/ConnectionTimeoutException_arginfo.h index c879338c1..fbc8cc103 100644 --- a/src/MongoDB/Exception/ConnectionTimeoutException_arginfo.h +++ b/src/MongoDB/Exception/ConnectionTimeoutException_arginfo.h @@ -1,10 +1,15 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 60470413296405ec96e76e4331835d8a27dd5ade */ + * Stub hash: f009e1098216b7f5d7fb9643c0dc98916bdcc631 */ +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_MongoDB_Driver_Exception_ConnectionTimeoutException_getWriteResult, 0, 0, MongoDB\\Driver\\WriteResult, 0) +ZEND_END_ARG_INFO() +static ZEND_METHOD(MongoDB_Driver_Exception_ConnectionTimeoutException, getWriteResult); + static const zend_function_entry class_MongoDB_Driver_Exception_ConnectionTimeoutException_methods[] = { + ZEND_ME(MongoDB_Driver_Exception_ConnectionTimeoutException, getWriteResult, arginfo_class_MongoDB_Driver_Exception_ConnectionTimeoutException_getWriteResult, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_FE_END }; @@ -16,5 +21,11 @@ static zend_class_entry *register_class_MongoDB_Driver_Exception_ConnectionTimeo class_entry = zend_register_internal_class_ex(&ce, class_entry_MongoDB_Driver_Exception_ConnectionException); class_entry->ce_flags |= ZEND_ACC_FINAL; + zval property_writeResult_default_value; + ZVAL_NULL(&property_writeResult_default_value); + zend_string *property_writeResult_name = zend_string_init("writeResult", sizeof("writeResult") - 1, 1); + zend_declare_typed_property(class_entry, property_writeResult_name, &property_writeResult_default_value, ZEND_ACC_PROTECTED, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); + zend_string_release(property_writeResult_name); + return class_entry; } diff --git a/src/phongo_execute.c b/src/phongo_execute.c index dee4291a9..63082886a 100644 --- a/src/phongo_execute.c +++ b/src/phongo_execute.c @@ -296,29 +296,14 @@ bool phongo_execute_bulk_write(zval* manager, const char* namespace, php_phongo_ /* A BulkWriteException is always thrown if mongoc_bulk_operation_execute() * fails to ensure that the write result is accessible. If the error does * not originate from the server (e.g. socket error), throw the appropriate - * exception first. It will be included in BulkWriteException's message and - * will also be accessible via Exception::getPrevious(). */ + * exception first. It will be thrown directly */ if (!success) { if (error.domain != MONGOC_ERROR_SERVER && error.domain != MONGOC_ERROR_WRITE_CONCERN) { phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply); - } - - /* Argument errors occur before command execution, so there is no need - * to layer this InvalidArgumentException behind a BulkWriteException. - * In practice, this will be a "Cannot do an empty bulk write" error. */ - if (error.domain == MONGOC_ERROR_COMMAND && error.code == MONGOC_ERROR_COMMAND_INVALID_ARG) { goto cleanup; } - if (EG(exception)) { - char* message; - - (void) spprintf(&message, 0, "Bulk write failed due to previous %s: %s", PHONGO_ZVAL_EXCEPTION_NAME(EG(exception)), error.message); - zend_throw_exception(php_phongo_bulkwriteexception_ce, message, 0); - efree(message); - } else { - zend_throw_exception(php_phongo_bulkwriteexception_ce, error.message, error.code); - } + zend_throw_exception(php_phongo_bulkwriteexception_ce, error.message, error.code); /* Ensure error labels are added to the final BulkWriteException. If a * previous exception was also thrown, error labels will already have diff --git a/tests/manager/manager-executeBulkWrite_error-005.phpt b/tests/manager/manager-executeBulkWrite_error-005.phpt index 3ce2e6de2..47a8c73b0 100644 --- a/tests/manager/manager-executeBulkWrite_error-005.phpt +++ b/tests/manager/manager-executeBulkWrite_error-005.phpt @@ -24,45 +24,14 @@ $bulk->insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 1]]); $bulk->delete(['x' => 1]); -try { +echo throws(function() use ($server, $bulk) { $server->executeBulkWrite(NS, $bulk); -} catch (MongoDB\Driver\Exception\BulkWriteException $e) { - printf("%s(%d): %s\n", get_class($e), $e->getCode(), $e->getMessage()); - $prev = $e->getPrevious(); - printf("%s(%d): %s\n", get_class($prev), $prev->getCode(), $prev->getMessage()); - var_dump($e->getWriteResult()); -} +}, MongoDB\Driver\Exception\ConnectionTimeoutException::class), "\n"; ?> ===DONE=== --EXPECTF-- -MongoDB\Driver\Exception\BulkWriteException(0): Bulk write failed due to previous MongoDB\Driver\Exception\ConnectionTimeoutException: Failed to send "delete" command with database "%s": Failed to read 4 bytes: socket error or timeout -MongoDB\Driver\Exception\ConnectionTimeoutException(%d): Failed to send "delete" command with database "%s": Failed to read 4 bytes: socket error or timeout -object(MongoDB\Driver\WriteResult)#%d (%d) { - ["nInserted"]=> - int(1) - ["nMatched"]=> - int(1) - ["nModified"]=> - int(1) - ["nRemoved"]=> - int(0) - ["nUpserted"]=> - int(0) - ["upsertedIds"]=> - array(0) { - } - ["writeErrors"]=> - array(0) { - } - ["writeConcernError"]=> - NULL - ["writeConcern"]=> - object(MongoDB\Driver\WriteConcern)#%d (%d) { - } - ["errorReplies"]=> - array(0) { - } -} +OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException +Failed to send "delete" command with database "%s": Failed to read 4 bytes: socket error or timeout ===DONE===