|
64 | 64 |
|
65 | 65 | S3Config = namedtuple("S3Config", "role session_vars client_params")
|
66 | 66 |
|
| 67 | +# Permission or access-related errors → 403 Forbidden |
| 68 | +PERMISSION_ERRORS = { |
| 69 | + "AccessDenied", |
| 70 | + "AccessDeniedException", |
| 71 | + "AccountProblem", |
| 72 | + "AllAccessDisabled", |
| 73 | + "AuthFailure", |
| 74 | + "ExpiredToken", |
| 75 | + "InvalidAccessKeyId", |
| 76 | + "InvalidSecurity", |
| 77 | + "SignatureDoesNotMatch", |
| 78 | + "UnauthorizedOperation", |
| 79 | + "UnrecognizedClientException", |
| 80 | +} |
| 81 | + |
| 82 | +# Not found errors → 404 Not Found |
| 83 | +NOT_FOUND_ERRORS = { |
| 84 | + "NoSuchBucket", |
| 85 | + "NoSuchKey", |
| 86 | + "NotFound", |
| 87 | +} |
| 88 | + |
| 89 | +# Range/invalid byte-range errors → 416 |
| 90 | +RANGE_ERRORS = { |
| 91 | + "InvalidRange", |
| 92 | +} |
| 93 | + |
| 94 | +# Server-side throttling, timeout, or transient errors → 503 |
| 95 | +# https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html |
| 96 | +TRANSIENT_ERRORS = { |
| 97 | + "BandwidthLimitExceeded", |
| 98 | + "ConnectionError", |
| 99 | + "EC2ThrottledException", |
| 100 | + "HTTPClientError", |
| 101 | + "InternalError", |
| 102 | + "InternalFailure", |
| 103 | + "LimitExceededException", |
| 104 | + "PriorRequestNotComplete", |
| 105 | + "ProvisionedThroughputExceededException", |
| 106 | + "RequestLimitExceeded", |
| 107 | + "RequestThrottled", |
| 108 | + "RequestThrottledException", |
| 109 | + "RequestTimeout", |
| 110 | + "RequestTimeoutException", |
| 111 | + "ServerError", |
| 112 | + "ServiceUnavailable", |
| 113 | + "SlowDown", |
| 114 | + "ThrottledException", |
| 115 | + "Throttling", |
| 116 | + "ThrottlingException", |
| 117 | + "TooManyRequestsException", |
| 118 | + "TransactionInProgressException", |
| 119 | + "Unavailable", |
| 120 | +} |
| 121 | + |
| 122 | +# Fatal/unrecoverable → 400 |
| 123 | +FATAL_ERRORS = { |
| 124 | + "BucketAlreadyExists", |
| 125 | + "BucketAlreadyOwnedByYou", |
| 126 | + "DryRunOperation", |
| 127 | + "InvalidClientTokenId", |
| 128 | + "InvalidParameterCombination", |
| 129 | + "InvalidParameterValue", |
| 130 | + "InvalidQueryParameter", |
| 131 | + "MalformedPolicyDocument", |
| 132 | + "MalformedQueryString", |
| 133 | + "MethodNotAllowed", |
| 134 | + "MissingParameter", |
| 135 | + "OperationAborted", |
| 136 | + "OptInRequired", |
| 137 | + "UnsupportedOperation", |
| 138 | + "UnsupportedProtocol", |
| 139 | + "ValidationException", |
| 140 | +} |
| 141 | + |
67 | 142 |
|
68 | 143 | class S3Url(object):
|
69 | 144 | def __init__(
|
@@ -132,90 +207,15 @@ def normalize_client_error(err):
|
132 | 207 | except ValueError:
|
133 | 208 | pass
|
134 | 209 |
|
135 |
| - # Permission or access-related errors → 403 Forbidden |
136 |
| - permission_errors = { |
137 |
| - "AccessDenied", |
138 |
| - "AccessDeniedException", |
139 |
| - "AccountProblem", |
140 |
| - "AllAccessDisabled", |
141 |
| - "AuthFailure", |
142 |
| - "ExpiredToken", |
143 |
| - "InvalidAccessKeyId", |
144 |
| - "InvalidSecurity", |
145 |
| - "SignatureDoesNotMatch", |
146 |
| - "UnauthorizedOperation", |
147 |
| - "UnrecognizedClientException", |
148 |
| - } |
149 |
| - |
150 |
| - # Not found errors → 404 Not Found |
151 |
| - not_found_errors = { |
152 |
| - "NoSuchBucket", |
153 |
| - "NoSuchKey", |
154 |
| - "NotFound", |
155 |
| - } |
156 |
| - |
157 |
| - # Range/invalid byte-range errors → 416 |
158 |
| - range_errors = { |
159 |
| - "InvalidRange", |
160 |
| - } |
161 |
| - |
162 |
| - # Server-side throttling, timeout, or transient errors → 503 |
163 |
| - # https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html |
164 |
| - transient_errors = { |
165 |
| - "BandwidthLimitExceeded", |
166 |
| - "ConnectionError", |
167 |
| - "EC2ThrottledException", |
168 |
| - "HTTPClientError", |
169 |
| - "InternalError", |
170 |
| - "InternalFailure", |
171 |
| - "LimitExceededException", |
172 |
| - "PriorRequestNotComplete", |
173 |
| - "ProvisionedThroughputExceededException", |
174 |
| - "RequestLimitExceeded", |
175 |
| - "RequestThrottled", |
176 |
| - "RequestThrottledException", |
177 |
| - "RequestTimeout", |
178 |
| - "RequestTimeoutException", |
179 |
| - "ServerError", |
180 |
| - "ServiceUnavailable", |
181 |
| - "SlowDown", |
182 |
| - "ThrottledException", |
183 |
| - "Throttling", |
184 |
| - "ThrottlingException", |
185 |
| - "TooManyRequestsException", |
186 |
| - "TransactionInProgressException", |
187 |
| - "Unavailable", |
188 |
| - } |
189 |
| - |
190 |
| - # Fatal/unrecoverable → 400 |
191 |
| - fatal_errors = { |
192 |
| - "BucketAlreadyExists", |
193 |
| - "BucketAlreadyOwnedByYou", |
194 |
| - "DryRunOperation", |
195 |
| - "InvalidClientTokenId", |
196 |
| - "InvalidParameterCombination", |
197 |
| - "InvalidParameterValue", |
198 |
| - "InvalidQueryParameter", |
199 |
| - "MalformedPolicyDocument", |
200 |
| - "MalformedQueryString", |
201 |
| - "MethodNotAllowed", |
202 |
| - "MissingParameter", |
203 |
| - "OperationAborted", |
204 |
| - "OptInRequired", |
205 |
| - "UnsupportedOperation", |
206 |
| - "UnsupportedProtocol", |
207 |
| - "ValidationException", |
208 |
| - } |
209 |
| - |
210 |
| - if error_code in permission_errors: |
| 210 | + if error_code in PERMISSION_ERRORS: |
211 | 211 | return 403
|
212 |
| - elif error_code in not_found_errors: |
| 212 | + elif error_code in NOT_FOUND_ERRORS: |
213 | 213 | return 404
|
214 |
| - elif error_code in range_errors: |
| 214 | + elif error_code in RANGE_ERRORS: |
215 | 215 | return 416
|
216 |
| - elif error_code in fatal_errors: |
| 216 | + elif error_code in FATAL_ERRORS: |
217 | 217 | return 400
|
218 |
| - elif error_code in transient_errors: |
| 218 | + elif error_code in TRANSIENT_ERRORS: |
219 | 219 | return 503
|
220 | 220 |
|
221 | 221 | # Default: return original string code if unmapped
|
|
0 commit comments