Comments (4)
AIODynamoError can be adjusted as follows:
class AIODynamoError(Exception):
def __init__(self, response_body: Optional[bytes] = None):
self.response_body = response_body
super().__init__(response_body)
And send_request can be modified as follows:
async def send_request(
self,
*,
action: str,
payload: Mapping[str, Any],
) -> Dict[str, Any]:
"""
Send a request to DynamoDB and handle retries if necessary.
The self.throttle_config.attempts() async iterable handles retries
by yielding each time we should do another attempt and raising
RetryTimeout once the time limit is reached.
In each iteration of the loop, we send a request to DynamoDB and check
its result. If it's good, we break out of the loop and return the parsed
JSON data to the caller.
If a non-200 status is returned, we determine the error type via
exception_from_response and check if we should retry. If we should retry,
log the error and go to the next iteration, otherwise raise the exception.
In either case, we store the last exception found so if we hit the retry
limit, we raise that exception.
If the loop never executed, we raise a BrokenThrottleConfig because
RetryConfig.attempts() should always yield at least once.
"""
exception: Optional[Exception] = None
try:
async for _ in self.throttle_config.attempts():
key = await self.credentials.get_key(self.http)
if key is None:
logger.debug("no credentials found")
exception = NoCredentialsFound()
continue
request = signed_dynamo_request(
key=key,
payload=payload,
action=action,
region=self.region,
endpoint=self.endpoint,
)
logger.debug("sending request %r", request)
try:
response = await self.http(
Request(
method="POST",
url=str(request.url),
headers=request.headers,
body=request.body,
)
)
except asyncio.TimeoutError as exc:
logger.debug("http timeout")
exception = exc
continue
except RequestFailed as exc:
logger.debug("request failed")
exception = exc.inner
continue
logger.debug("got response %r", response)
if response.status == 200:
return cast(Dict[str, Any], json.loads(response.body))
exception = exception_from_response(response.status, response.body)
if isinstance(exception, AIODynamoError):
exception.response_body = response.body
if isinstance(exception, Throttled):
logger.debug("request throttled")
elif isinstance(exception, ProvisionedThroughputExceeded):
logger.debug("provisioned throughput exceeded")
elif isinstance(exception, ExpiredToken):
logger.debug("token expired")
if not self.credentials.invalidate():
raise exception
elif isinstance(exception, ServiceUnavailable):
logger.debug("service unavailable")
elif isinstance(exception, InternalDynamoError):
logger.debug("internal dynamo error")
else:
raise exception
except RetryTimeout:
if exception is not None:
raise exception
raise
raise BrokenThrottleConfig()
from aiodynamo.
My 2c: I'm not sure if the enhancement is really needed, however, if the response is an error response, there's hardly any overhead.
I'd entertain a draft PR to understand the proposal in detail.
What I wonder though, is to expose the error details in a convenient way. Let's say the caller does except Exception: logging.exception("oops")
, should the extra info show up in __str__
or __repr__
of the exception? Some other way?
from aiodynamo.
known AIODynamoError
already store the (json-decoded) response in .args[0]
. UnkownError
stores both the status and the (raw) response. Is that not enough?
from aiodynamo.
@ojii You're right. Thank you.
from aiodynamo.
Related Issues (20)
- Support for applications running on Kubernetes
- after moving to github actions, integration tests are no longer run
- Add Amazon DynamoDB Accelerator (DAX) support to the library HOT 3
- Surprising behaviour in `Client.table_exists` HOT 1
- Auth Error With No Default Credentials HOT 1
- Unable to use AWS_REGION env var HOT 3
- Support AWS Web Identity Token File authentication HOT 2
- Shall we try goodfirstissue.dev ?
- Empty-set safety HOT 3
- Session instantiation HOT 6
- Get most recently added entry HOT 5
- ECS Fargate Credentials Compatibility HOT 2
- Support for typing-extensions version 4 module HOT 2
- Update maximum transaction operations to 100 HOT 1
- InstanceMetadataCredentials does not work with IMDSv2 HOT 5
- Awkward API for handling `TransactionCanceled` from `transact_write_items` HOT 2
- await table.exists() is stuck/hanging HOT 3
- Documentation in other languages, maybe?
- `FileCredentials()` doesn't support credentials retrieved with AWS CLI v2 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aiodynamo.