@@ -368,21 +368,42 @@ bool phongo_execute_bulkwritecommand(zval* manager, php_phongo_bulkwritecommand_
368
368
369
369
bwcr = phongo_bulkwritecommandresult_init (return_value , & bw_ret , manager );
370
370
371
+ /* Error handling for mongoc_bulkwrite_execute differs significantly from
372
+ * mongoc_bulk_operation_execute.
373
+ *
374
+ * - There may or may not be a top-level error. Top-level errors include
375
+ * both logical errors (invalid arguments) and runtime errors (e.g. server
376
+ * selection failure). A bulk write fails due to write or write concern
377
+ * errors will typically not have a top-level error.
378
+ *
379
+ * - There may or may not be an error reply document. This document could be
380
+ * the response of a failed bulkWrite command, but it may also originate
381
+ * from libmongoc (e.g. server selection, appending a session, iterating
382
+ * BSON). This function only uses it to extrapolate error labels and it is
383
+ * otherwise accessible to the user through BulkWriteCommandResult.
384
+ *
385
+ * - InvalidArgumentException may be thrown directly for a basic top-level
386
+ * error (assuming BulkWriteCommandResult would also be irrelevant).
387
+ * Otherwise, BulkWriteCommandException is thrown with an attached
388
+ * BulkWriteCommandResult that collects any error reply, write errors, and
389
+ * write concern errors, along with a possible partial write result.
390
+ */
371
391
if (bw_ret .exc ) {
372
392
success = false;
373
393
bson_error_t error = { 0 };
394
+ const bson_t * error_reply = mongoc_bulkwriteexception_errorreply (bw_ret .exc );
374
395
375
- // Check if there is a top-level error
396
+ // Consult any top-level error to throw the first exception
376
397
if (mongoc_bulkwriteexception_error (bw_ret .exc , & error )) {
377
- phongo_throw_exception_from_bson_error_t_and_reply (& error , mongoc_bulkwriteexception_errorreply ( bw_ret . exc ) );
398
+ phongo_throw_exception_from_bson_error_t_and_reply (& error , error_reply );
378
399
}
379
400
380
401
/* Unlike mongoc_bulk_operation_execute, mongoc_bulkwrite_execute may
381
- * report COMMAND_INVALID_ARG alongside a partial result (CDRIVER-5842).
382
- * If there is no result, we can throw InvalidArgumentException without
383
- * proxying it behind a BulkWriteException. */
384
- if (! bw_ret . res && error . domain == MONGOC_ERROR_COMMAND && error . code == MONGOC_ERROR_COMMAND_INVALID_ARG ) {
385
- // TODO: Do we care about other mongoc_bulkwriteexception_t fields?
402
+ * report MONGOC_ERROR_COMMAND_INVALID_ARG alongside a partial result
403
+ * (CDRIVER-5842). Throw InvalidArgumentException directly iff there is
404
+ * neither a partial write result nor an error reply (we can assume
405
+ * there are no write or write concern errors for this case). */
406
+ if ( EG ( exception ) && EG ( exception ) -> ce == php_phongo_invalidargumentexception_ce && ! bw_ret . res && ! error_reply ) {
386
407
goto cleanup ;
387
408
}
388
409
@@ -393,14 +414,14 @@ bool phongo_execute_bulkwritecommand(zval* manager, php_phongo_bulkwritecommand_
393
414
zend_throw_exception (php_phongo_bulkwritecommandexception_ce , message , 0 );
394
415
efree (message );
395
416
} else {
396
- // TODO: Determine appropriate message w/o top-level error
397
417
zend_throw_exception (php_phongo_bulkwritecommandexception_ce , "Bulk write failed" , 0 );
398
418
}
399
419
400
- /* Ensure error labels are added to the final BulkWriteCommandException. If a
401
- * previous exception was also thrown, error labels will already have
402
- * been added by phongo_throw_exception_from_bson_error_t_and_reply. */
403
- phongo_exception_add_error_labels (mongoc_bulkwriteexception_errorreply (bw_ret .exc ));
420
+ /* Ensure error labels are added to the final BulkWriteCommandException.
421
+ * If RuntimeException was previously thrown, labels may also have been
422
+ * added to it by phongo_throw_exception_from_bson_error_t_and_reply. */
423
+ phongo_exception_add_error_labels (error_reply );
424
+
404
425
phongo_add_exception_prop (ZEND_STRL ("bulkWriteCommandResult" ), return_value );
405
426
}
406
427
0 commit comments