Coder Social home page Coder Social logo

Comments (4)

darro45 avatar darro45 commented on July 22, 2024

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.

dimaqq avatar dimaqq commented on July 22, 2024

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.

ojii avatar ojii commented on July 22, 2024

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.

darro45 avatar darro45 commented on July 22, 2024

@ojii You're right. Thank you.

from aiodynamo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.