예제 #1
0
def unenvelope_or_raise_error(resp: httpx.Response) -> Dict:
    """
    Director responses are enveloped
    If successful response, we un-envelop it and return data as a dict
    If error, it raise an HTTPException
    """
    body = resp.json()

    assert "data" in body or "error" in body  # nosec
    data = body.get("data")
    error = body.get("error")

    if codes.is_server_error(resp.status_code):
        logger.error(
            "director error %d [%s]: %s",
            resp.status_code,
            resp.reason_phrase,
            error,
        )
        raise HTTPException(status.HTTP_503_SERVICE_UNAVAILABLE)

    if codes.is_client_error(resp.status_code):
        msg = error or resp.reason_phrase
        raise HTTPException(resp.status_code, detail=msg)

    return data or {}
예제 #2
0
    def _process(cls, resp: Response) -> Optional[JSON]:
        # enveloped answer
        data, error = None, None
        try:
            body = resp.json()
            data, error = body.get("data"), body.get("error")
        except (json.JSONDecodeError, KeyError):
            logger.warning("Failed to unenvelop webserver response", exc_info=True)

        if codes.is_server_error(resp.status_code):
            logger.error(
                "webserver error %d [%s]: %s",
                resp.status_code,
                resp.reason_phrase,
                error,
            )
            raise HTTPException(status.HTTP_503_SERVICE_UNAVAILABLE)

        if codes.is_client_error(resp.status_code):
            msg = error or resp.reason_phrase
            raise HTTPException(resp.status_code, detail=msg)

        return data
예제 #3
0
    async def _dispatch_send(
        self,
        request: Request,
        *,
        timeout: float = None,
        retry_count: int = None,
    ):
        """

        TODO: need better implementation for retry

        :param request:
        :param timeout:
        :param retry_count:
        """
        attempts = 1
        if request.method == "GET":
            attempts += (settings.SERVICE_CONNECTION_DEFAULT_RETRY_COUNT
                         if retry_count is None else min(
                             retry_count,
                             int(settings.SERVICE_CONNECTION_MAX_RETRY_COUNT),
                         ))

        for i in range(attempts):
            try:
                response = await self.client.send(request, timeout=timeout)

                if codes.is_server_error(response.status_code):
                    response.raise_for_status()

            except (TransportError, HTTPStatusError,
                    ConnectionResetError) as e:
                error_logger.debug(f"{str(e)} on attempt {i}")
                if i + 1 >= attempts:
                    raise
            else:
                return response