@@ -423,7 +423,9 @@ def _translate_errors(cls, fcn, post_params=None):
423423 # Decode the error object returned by the service
424424 try :
425425 error = json .loads (response .content .decode ('utf-8' )) if response .content else {}
426- except (json .JSONDecodeError , UnicodeDecodeError ):
426+ if not isinstance (error , dict ):
427+ raise ValueError ('json error value is not a dict' )
428+ except (json .JSONDecodeError , UnicodeDecodeError , ValueError ):
427429 logger .error ('failed to decode error response: %r' , response .content )
428430 # When the user points to an S3 endpoint, he won't receive the JSON error
429431 # he expects. In that case, we can provide at least a hint of "what happened".
@@ -439,10 +441,22 @@ def _translate_errors(cls, fcn, post_params=None):
439441 logger .debug (
440442 'received error has extra (unsupported) keys: %s' , extra_error_keys
441443 )
444+
445+ try :
446+ status = int (error .get ('status' , response .status_code ))
447+ if status != response .status_code :
448+ raise ValueError ('status code is not equal to the one in the response' )
449+ except (TypeError , ValueError ) as exc :
450+ logger .warning (
451+ 'Inconsistent status codes returned by the server %r != %r; parsing exception: %r' ,
452+ error .get ('status' ), response .status_code , exc
453+ )
454+ status = response .status_code
455+
442456 raise interpret_b2_error (
443- int ( error . get ( ' status' , response . status_code )) ,
444- error . get ( 'code' ) ,
445- error . get ( 'message' ) ,
457+ status ,
458+ str ( error [ 'code' ]) if 'code' in error else None ,
459+ str ( error [ 'message' ]) if 'message' in error else None ,
446460 response .headers ,
447461 post_params ,
448462 )
0 commit comments