@@ -417,7 +417,11 @@ class MongoClientInterface {
417
417
} , payload , {
418
418
upsert : true ,
419
419
} )
420
- . then ( ( ) => {
420
+ . then ( result => {
421
+ if ( result . modifiedCount === 0 && result . upsertedCount === 0 ) {
422
+ log . debug ( 'createBucket: failed to create bucket' , { bucketName } ) ;
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 . modifiedCount === 0 && result . upsertedCount === 0 ) {
592
+ log . debug ( 'putBucketAttributes: failed to update bucket' , { bucketName } ) ;
593
+ return cb ( errors . InternalError ) ;
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,7 +2065,19 @@ 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
+ if ( ! result || ! result . ok ) {
2070
+ log . debug ( 'internalDeleteObject: bulk operation failed' ,
2071
+ { bucket : bucketName , object : key } ) ;
2072
+ return next ( errors . InternalError ) ;
2073
+ }
2074
+ if ( result . deletedCount === 0 ) {
2075
+ log . debug ( 'internalDeleteObject: object not deleted' ,
2076
+ { bucket : bucketName , object : key } ) ;
2077
+ return next ( errors . NoSuchKey ) ;
2078
+ }
2079
+ return next ( null ) ;
2080
+ } ) . catch ( err => next ( err ) ) ,
2034
2081
] , ( err , res ) => {
2035
2082
if ( err ) {
2036
2083
if ( err instanceof ArsenalError && err . is . NoSuchKey ) {
@@ -2396,7 +2443,13 @@ class MongoClientInterface {
2396
2443
i . insertOne ( < InfostoreDocument > {
2397
2444
_id : __UUID ,
2398
2445
value : uuid ,
2399
- } , { } ) . then ( ( ) => cb ( null ) ) // FIXME: shoud we check for result.ok === 1 ?
2446
+ } , { } ) . then ( result => {
2447
+ if ( ! result || ! result . acknowledged ) {
2448
+ log . debug ( 'writeUUIDIfNotExists: insertion failed' ) ;
2449
+ return cb ( errors . InternalError ) ;
2450
+ }
2451
+ return cb ( null ) ;
2452
+ } )
2400
2453
. catch ( err => {
2401
2454
if ( err . code === 11000 ) {
2402
2455
// duplicate key error
@@ -3124,7 +3177,13 @@ class MongoClientInterface {
3124
3177
putBucketIndexes ( bucketName : string , indexSpecs , log : werelogs . Logger , cb : ArsenalCallback < void > ) {
3125
3178
const c = this . getCollection < ObjectMetastoreDocument > ( bucketName ) ;
3126
3179
const indexes = MongoUtils . indexFormatObjectToMongoArray ( indexSpecs ) ;
3127
- c . createIndexes ( indexes ) . then ( ( ) => cb ( null ) ) . catch ( err => {
3180
+ c . createIndexes ( indexes ) . then ( result => {
3181
+ if ( ! result ) {
3182
+ log . debug ( 'putBucketIndexes: failed creating bucket indexes' ) ;
3183
+ return cb ( errors . InternalError ) ;
3184
+ }
3185
+ return cb ( null ) ;
3186
+ } ) . catch ( err => {
3128
3187
if ( err . codeName === 'NamespaceNotFound' ) {
3129
3188
return cb ( errors . NoSuchBucket ) ;
3130
3189
}
@@ -3147,7 +3206,13 @@ class MongoClientInterface {
3147
3206
deleteBucketIndexes ( bucketName : string , indexSpecs : { name : string } [ ] , log : werelogs . Logger , cb : ArsenalCallback < void > ) {
3148
3207
const c = this . getCollection < ObjectMetastoreDocument > ( bucketName ) ;
3149
3208
async . each ( indexSpecs ,
3150
- ( spec , next ) => c . dropIndex ( spec . name ) . then ( ( ) => next ( ) ) . catch ( err => next ( err ) ) ,
3209
+ ( spec , next ) => c . dropIndex ( spec . name ) . then ( result => {
3210
+ if ( ! result || ! result . ok ) {
3211
+ log . debug ( 'deleteBucketIndexes: failed to drop index' , { indexName : spec . name } ) ;
3212
+ return next ( new Error ( 'Failed to drop index' ) ) ;
3213
+ }
3214
+ return next ( ) ;
3215
+ } ) . catch ( err => next ( err ) ) ,
3151
3216
err => {
3152
3217
if ( err ) {
3153
3218
if ( err instanceof MongoServerError && err . codeName === 'NamespaceNotFound' ) {
0 commit comments