@@ -417,7 +417,11 @@ class MongoClientInterface {
417
417
} , payload , {
418
418
upsert : true ,
419
419
} )
420
- . then ( ( ) => {
420
+ . then ( result => {
421
+ if ( result . matchedCount === 0 && result . modifiedCount === 0 && result . upsertedCount === 0 ) {
422
+ log . debug ( 'createBucket: failed to create bucket' , { bucketName, result } ) ;
423
+ return cb ( errors . InternalError ) ;
424
+ }
421
425
// caching bucket vFormat
422
426
this . bucketVFormatCache . add ( bucketName , payload . $set . vFormat ) ;
423
427
// NOTE: We do not need to create a collection for
@@ -583,7 +587,13 @@ class MongoClientInterface {
583
587
} , {
584
588
upsert : true ,
585
589
} )
586
- . then ( ( ) => cb ( null ) )
590
+ . then ( result => {
591
+ if ( result . matchedCount === 0 && result . modifiedCount === 0 && result . upsertedCount === 0 ) {
592
+ log . debug ( 'putBucketAttributes: failed to update bucket' , { bucketName } ) ;
593
+ return cb ( errors . NoSuchBucket ) ;
594
+ }
595
+ return cb ( null ) ;
596
+ } )
587
597
. catch ( err => {
588
598
log . error (
589
599
'putBucketAttributes: error putting bucket attributes' ,
@@ -623,7 +633,13 @@ class MongoClientInterface {
623
633
} ,
624
634
} , {
625
635
upsert : true ,
626
- } ) . then ( ( ) => cb ( null ) ) . catch ( err => {
636
+ } ) . then ( result => {
637
+ if ( result . modifiedCount === 0 && result . upsertedCount === 0 ) {
638
+ log . error ( 'putBucketAttributesCapabilities: failed to update bucket' , { bucketName } ) ;
639
+ return cb ( errors . InternalError ) ;
640
+ }
641
+ return cb ( null ) ;
642
+ } ) . catch ( err => {
627
643
log . error (
628
644
'putBucketAttributesCapabilities: error putting bucket attributes' ,
629
645
{ error : err . message } ) ;
@@ -657,7 +673,14 @@ class MongoClientInterface {
657
673
$unset : {
658
674
[ updateString ] : '' ,
659
675
} ,
660
- } ) . then ( ( ) => cb ( null ) ) . catch ( err => {
676
+ } ) . then ( result => {
677
+ if ( result . modifiedCount === 0 ) {
678
+ log . debug ( 'deleteBucketAttributesCapability: bucket not found or capability not present' ,
679
+ { bucketName } ) ;
680
+ return cb ( errors . NoSuchBucket ) ;
681
+ }
682
+ return cb ( null ) ;
683
+ } ) . catch ( err => {
661
684
if ( err ) {
662
685
log . error (
663
686
'deleteBucketAttributesCapability: error deleting bucket attributes' ,
@@ -1967,7 +1990,19 @@ class MongoClientInterface {
1967
1990
if ( params && params . doesNotNeedOpogUpdate ) {
1968
1991
// If flag is true, directly delete object
1969
1992
return collection . deleteOne ( deleteFilter )
1970
- . then ( ( ) => cb ( null , undefined ) )
1993
+ . then ( result => {
1994
+ // In case of race conditions (e.g. two concurrent deletes), or invalid state
1995
+ // (e.g. object is already deleted), the result.deletedCount will be 0
1996
+ // without error, and we need to catch it because the API might continue and
1997
+ // delete the actual data, leading to an invalid state, where MongoDB references
1998
+ // and object not in the data layers anymore.
1999
+ if ( ! result || result ?. deletedCount != 1 ) {
2000
+ log . debug ( 'internalDeleteObject: object not found or already deleted' ,
2001
+ { bucket : bucketName , object : key } ) ;
2002
+ return cb ( errors . NoSuchKey ) ;
2003
+ }
2004
+ return cb ( null , undefined ) ;
2005
+ } )
1971
2006
. catch ( err => {
1972
2007
log . error ( 'internalDeleteObject: error deleting object' ,
1973
2008
{ bucket : bucketName , object : key , error : err . message } ) ;
@@ -2030,10 +2065,24 @@ class MongoClientInterface {
2030
2065
filter : updateDeleteFilter ,
2031
2066
} ,
2032
2067
} ,
2033
- ] , { ordered : true } ) . then ( ( ) => next ( null ) ) . catch ( err => next ( err ) ) ,
2068
+ ] , { ordered : true } ) . then ( result => {
2069
+ // in case of race conditions, the bulk operation might fail
2070
+ // in this case we return a DeleteConflict error
2071
+ if ( ! result || ! result . ok ) {
2072
+ log . debug ( 'internalDeleteObject: bulk operation failed' ,
2073
+ { bucket : bucketName , object : key } ) ;
2074
+ return next ( errors . DeleteConflict ) ;
2075
+ }
2076
+ if ( result . deletedCount === 0 ) {
2077
+ log . debug ( 'internalDeleteObject: object not found or already deleted' ,
2078
+ { bucket : bucketName , object : key } ) ;
2079
+ return next ( errors . DeleteConflict ) ;
2080
+ }
2081
+ return next ( null ) ;
2082
+ } ) . catch ( err => next ( err ) ) ,
2034
2083
] , ( err , res ) => {
2035
2084
if ( err ) {
2036
- if ( err instanceof ArsenalError && err . is . NoSuchKey ) {
2085
+ if ( err instanceof ArsenalError ) {
2037
2086
return cb ( err ) ;
2038
2087
}
2039
2088
log . error ( 'internalDeleteObject: error deleting object' ,
@@ -2396,7 +2445,13 @@ class MongoClientInterface {
2396
2445
i . insertOne ( < InfostoreDocument > {
2397
2446
_id : __UUID ,
2398
2447
value : uuid ,
2399
- } , { } ) . then ( ( ) => cb ( null ) ) // FIXME: shoud we check for result.ok === 1 ?
2448
+ } , { } ) . then ( result => {
2449
+ if ( ! result || ! result . acknowledged ) {
2450
+ log . debug ( 'writeUUIDIfNotExists: insertion failed' ) ;
2451
+ return cb ( errors . InternalError ) ;
2452
+ }
2453
+ return cb ( null ) ;
2454
+ } )
2400
2455
. catch ( err => {
2401
2456
if ( err . code === 11000 ) {
2402
2457
// duplicate key error
@@ -3147,7 +3202,13 @@ class MongoClientInterface {
3147
3202
deleteBucketIndexes ( bucketName : string , indexSpecs : { name : string } [ ] , log : werelogs . Logger , cb : ArsenalCallback < void > ) {
3148
3203
const c = this . getCollection < ObjectMetastoreDocument > ( bucketName ) ;
3149
3204
async . each ( indexSpecs ,
3150
- ( spec , next ) => c . dropIndex ( spec . name ) . then ( ( ) => next ( ) ) . catch ( err => next ( err ) ) ,
3205
+ ( spec , next ) => c . dropIndex ( spec . name ) . then ( result => {
3206
+ if ( ! result || ! result . ok ) {
3207
+ log . debug ( 'deleteBucketIndexes: failed to drop index' , { indexName : spec . name } ) ;
3208
+ return next ( errors . DeleteConflict ) ;
3209
+ }
3210
+ return next ( ) ;
3211
+ } ) . catch ( err => next ( err ) ) ,
3151
3212
err => {
3152
3213
if ( err ) {
3153
3214
if ( err instanceof MongoServerError && err . codeName === 'NamespaceNotFound' ) {
0 commit comments