Skip to content

Commit

Permalink
add NonPaymentHistory exception handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mjurbanski-reef committed Jun 7, 2024
1 parent 84f421b commit 09b286e
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 74 deletions.
11 changes: 9 additions & 2 deletions b2sdk/_internal/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,11 @@ def should_retry_upload(self):
return False


class NoPaymentHistory(Unauthorized):
def should_retry_upload(self):
return False


class InvalidAuthToken(Unauthorized):
"""
Specific type of Unauthorized that means the auth token is invalid.
Expand Down Expand Up @@ -613,6 +618,10 @@ def _event_type_invalid_error(code: str, message: str, **_) -> B2Error:
lambda code, message, **_: EventTypesEmptyError(message, code),
(400, "event_type_invalid"):
_event_type_invalid_error,
(401, "email_not_verified"):
lambda code, message, **_: EmailNotVerified(message, code),
(401, "no_payment_history"):
lambda code, message, **_: NoPaymentHistory(message, code),
}


Expand Down Expand Up @@ -705,8 +714,6 @@ def interpret_b2_error(
return BadRequest(message, code)
elif status == 401 and code in ("bad_auth_token", "expired_auth_token"):
return InvalidAuthToken(message, code)
elif status == 401 and code == 'email_not_verified':
return EmailNotVerified(message, code)
elif status == 401:
return Unauthorized(message, code)
elif status == 403 and code == "storage_cap_exceeded":
Expand Down
150 changes: 78 additions & 72 deletions b2sdk/_v3/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,83 +12,87 @@
from b2sdk._internal.account_info.exception import AccountInfoError
from b2sdk._internal.account_info.exception import CorruptAccountInfo
from b2sdk._internal.account_info.exception import MissingAccountData
from b2sdk._internal.exception import AccessDenied
from b2sdk._internal.exception import AlreadyFailed
from b2sdk._internal.exception import B2ConnectionError
from b2sdk._internal.exception import B2Error
from b2sdk._internal.exception import B2HttpCallbackException
from b2sdk._internal.exception import B2HttpCallbackPostRequestException
from b2sdk._internal.exception import B2HttpCallbackPreRequestException
from b2sdk._internal.exception import B2RequestTimeout
from b2sdk._internal.exception import B2RequestTimeoutDuringUpload
from b2sdk._internal.exception import B2SimpleError
from b2sdk._internal.exception import BadDateFormat
from b2sdk._internal.exception import BadFileInfo
from b2sdk._internal.exception import BadJson
from b2sdk._internal.exception import BadRequest
from b2sdk._internal.exception import BadUploadUrl
from b2sdk._internal.exception import BrokenPipe
from b2sdk._internal.exception import BucketIdNotFound
from b2sdk._internal.exception import BucketNotAllowed
from b2sdk._internal.exception import CapExceeded
from b2sdk._internal.exception import CapabilityNotAllowed
from b2sdk._internal.exception import ChecksumMismatch
from b2sdk._internal.exception import ClockSkew
from b2sdk._internal.exception import Conflict
from b2sdk._internal.exception import ConnectionReset
from b2sdk._internal.exception import CopyArgumentsMismatch
from b2sdk._internal.exception import DestFileNewer
from b2sdk._internal.exception import DestinationDirectoryDoesntAllowOperation
from b2sdk._internal.exception import DestinationDirectoryDoesntExist
from b2sdk._internal.exception import DestinationIsADirectory
from b2sdk._internal.exception import DestinationParentIsNotADirectory
from b2sdk._internal.exception import DisablingFileLockNotSupported
from b2sdk._internal.exception import DuplicateBucketName
from b2sdk._internal.exception import FileAlreadyHidden
from b2sdk._internal.exception import FileNameNotAllowed
from b2sdk._internal.exception import FileNotPresent
from b2sdk._internal.exception import FileSha1Mismatch
from b2sdk._internal.exception import InvalidAuthToken
from b2sdk._internal.exception import InvalidJsonResponse
from b2sdk._internal.exception import InvalidMetadataDirective
from b2sdk._internal.exception import InvalidRange
from b2sdk._internal.exception import InvalidUploadSource
from b2sdk._internal.exception import MaxFileSizeExceeded
from b2sdk._internal.exception import MaxRetriesExceeded
from b2sdk._internal.exception import MissingPart
from b2sdk._internal.exception import NonExistentBucket
from b2sdk._internal.exception import NotAllowedByAppKeyError
from b2sdk._internal.exception import PartSha1Mismatch
from b2sdk._internal.exception import PotentialS3EndpointPassedAsRealm
from b2sdk._internal.exception import RestrictedBucket
from b2sdk._internal.exception import RestrictedBucketMissing
from b2sdk._internal.exception import RetentionWriteError
from b2sdk._internal.exception import SSECKeyError
from b2sdk._internal.exception import SSECKeyIdMismatchInCopy
from b2sdk._internal.exception import ServiceError
from b2sdk._internal.exception import SourceReplicationConflict
from b2sdk._internal.exception import StorageCapExceeded
from b2sdk._internal.exception import TooManyRequests
from b2sdk._internal.exception import TransactionCapExceeded
from b2sdk._internal.exception import TransientErrorMixin
from b2sdk._internal.exception import TruncatedOutput
from b2sdk._internal.exception import Unauthorized
from b2sdk._internal.exception import UnexpectedCloudBehaviour
from b2sdk._internal.exception import UnknownError
from b2sdk._internal.exception import UnknownHost
from b2sdk._internal.exception import UnrecognizedBucketType
from b2sdk._internal.exception import UnsatisfiableRange
from b2sdk._internal.exception import UnusableFileName
from b2sdk._internal.exception import WrongEncryptionModeForBucketDefault
from b2sdk._internal.exception import interpret_b2_error
from b2sdk._internal.sync.exception import IncompleteSync
from b2sdk._internal.scan.exception import UnableToCreateDirectory
from b2sdk._internal.exception import (
AccessDenied,
AlreadyFailed,
B2ConnectionError,
B2Error,
B2HttpCallbackException,
B2HttpCallbackPostRequestException,
B2HttpCallbackPreRequestException,
B2RequestTimeout,
B2RequestTimeoutDuringUpload,
B2SimpleError,
BadDateFormat,
BadFileInfo,
BadJson,
BadRequest,
BadUploadUrl,
BrokenPipe,
BucketIdNotFound,
BucketNotAllowed,
CapabilityNotAllowed,
CapExceeded,
ChecksumMismatch,
ClockSkew,
Conflict,
ConnectionReset,
CopyArgumentsMismatch,
DestFileNewer,
DestinationDirectoryDoesntAllowOperation,
DestinationDirectoryDoesntExist,
DestinationIsADirectory,
DestinationParentIsNotADirectory,
DisablingFileLockNotSupported,
DuplicateBucketName,
EmailNotVerified,
FileAlreadyHidden,
FileNameNotAllowed,
FileNotPresent,
FileSha1Mismatch,
InvalidAuthToken,
InvalidJsonResponse,
InvalidMetadataDirective,
InvalidRange,
InvalidUploadSource,
MaxFileSizeExceeded,
MaxRetriesExceeded,
MissingPart,
NonExistentBucket,
NoPaymentHistory,
NotAllowedByAppKeyError,
PartSha1Mismatch,
PotentialS3EndpointPassedAsRealm,
RestrictedBucket,
RestrictedBucketMissing,
RetentionWriteError,
ServiceError,
SourceReplicationConflict,
SSECKeyError,
SSECKeyIdMismatchInCopy,
StorageCapExceeded,
TooManyRequests,
TransactionCapExceeded,
TransientErrorMixin,
TruncatedOutput,
Unauthorized,
UnexpectedCloudBehaviour,
UnknownError,
UnknownHost,
UnrecognizedBucketType,
UnsatisfiableRange,
UnusableFileName,
WrongEncryptionModeForBucketDefault,
interpret_b2_error,
)
from b2sdk._internal.scan.exception import EmptyDirectory
from b2sdk._internal.scan.exception import EnvironmentEncodingError
from b2sdk._internal.scan.exception import InvalidArgument
from b2sdk._internal.scan.exception import NotADirectory
from b2sdk._internal.scan.exception import UnableToCreateDirectory
from b2sdk._internal.scan.exception import UnsupportedFilename
from b2sdk._internal.scan.exception import check_invalid_argument
from b2sdk._internal.sync.exception import IncompleteSync

__all__ = (
'AccessDenied',
Expand All @@ -110,8 +114,8 @@
'BrokenPipe',
'BucketIdNotFound',
'BucketNotAllowed',
'CapExceeded',
'CapabilityNotAllowed',
'CapExceeded',
'ChecksumMismatch',
'ClockSkew',
'Conflict',
Expand All @@ -125,6 +129,7 @@
'DestinationParentIsNotADirectory',
'DisablingFileLockNotSupported',
'DuplicateBucketName',
'EmailNotVerified',
'EmptyDirectory',
'EnvironmentEncodingError',
'FileAlreadyHidden',
Expand All @@ -143,6 +148,7 @@
'MissingAccountData',
'MissingPart',
'NonExistentBucket',
'NoPaymentHistory',
'NotADirectory',
'NotAllowedByAppKeyError',
'PartSha1Mismatch',
Expand Down
2 changes: 2 additions & 0 deletions changelog.d/+NoPaymentHistory_exception.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add non-retryable `NoPaymentHistory` exception.
API returns this exception when action (e.g. bucket creation or replication rules) is not allowed due to lack of payment history.
13 changes: 13 additions & 0 deletions test/unit/test_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
CapExceeded,
Conflict,
DuplicateBucketName,
EmailNotVerified,
FileAlreadyHidden,
FileNotPresent,
InvalidAuthToken,
MissingPart,
NoPaymentHistory,
PartSha1Mismatch,
ServiceError,
StorageCapExceeded,
Expand Down Expand Up @@ -175,3 +177,14 @@ def _check_one(
actual_exception = interpret_b2_error(status, code, message, response_headers, post_params)
assert isinstance(actual_exception, expected_class)
return actual_exception

@pytest.mark.parametrize(
"status, code, expected_exception_cls", [
(401, "email_not_verified", EmailNotVerified),
(401, "no_payment_history", NoPaymentHistory),
]
)
def test_simple_error_handlers(self, status, code, expected_exception_cls):
error = interpret_b2_error(status, code, "", {})
assert isinstance(error, expected_exception_cls)
assert error.code == code

0 comments on commit 09b286e

Please sign in to comment.