コード例 #1
0
ファイル: errors.py プロジェクト: ztaylor54/kopf
async def check_response(response: aiohttp.ClientResponse, ) -> None:
    """
    Check for specialised K8s errors, and raise with extended information.
    """
    if response.status >= 400:

        # Read the response's body before it is closed by raise_for_status().
        payload: Optional[RawStatus]
        try:
            payload = await response.json()
        except (json.JSONDecodeError, aiohttp.ContentTypeError,
                aiohttp.ClientConnectionError):
            payload = None

        # Better be safe: who knows which sensitive information can be dumped unless kind==Status.
        if not isinstance(
                payload,
                collections.abc.Mapping) or payload.get('kind') != 'Status':
            payload = None

        cls = (APIUnauthorizedError if response.status == 401 else
               APIForbiddenError if response.status == 403 else
               APINotFoundError if response.status == 404 else APIError)

        # Raise the framework-specific error while keeping the original error in scope.
        # This call also closes the response's body, so it cannot be read afterwards.
        try:
            response.raise_for_status()
        except aiohttp.ClientResponseError as e:
            raise cls(payload, status=response.status) from e
コード例 #2
0
 async def _raise_for_status(resp: aiohttp.ClientResponse) -> None:
     """Check resp for status and if error log additional info."""
     try:
         resp.raise_for_status()
     except aiohttp.ClientResponseError:
         log.exception('Error body: %s', await resp.text())
         raise
コード例 #3
0
    async def _extract_response_data(
        resp: aiohttp.ClientResponse,
    ) -> list | dict:
        """Checks the correctness of the response.

        Args:
            resp: Response instance.

        Returns:
            resp['data'] field if expected data.

        Raises:
            aiohttp.ClientResponseError: if response status >= 400.
            aiohttp.ClientPayloadError: if failure result of the request.

            #TODO: refactor for process HTTP statuses!
        """
        resp.raise_for_status()

        json = await resp.json()
        if json.get("success"):
            _LOG.debug(
                "Successfully response",
                extra={
                    "url": resp.url,
                },
            )
            return json.get("data", {})
        raise aiohttp.ClientPayloadError(f"Failure server result: {resp.url} {json}")
コード例 #4
0
ファイル: session.py プロジェクト: AlexisH/gcloud-aio
 async def _raise_for_status(resp: aiohttp.ClientResponse) -> None:
     """Check resp for status and if error log additional info."""
     body = await resp.text(errors='replace')
     try:
         resp.raise_for_status()
     except aiohttp.ClientResponseError:
         log.exception('got http error response: %s', body)
         raise
コード例 #5
0
 def _check_status(r: aiohttp.ClientResponse, expected_status):
     r.raise_for_status()
     if r.status != expected_status:
         raise DSWCommunicationError(
             reason='Unexpected response status',
             message=f'Server responded with unexpected HTTP status {r.status}: '
                     f'{r.reason} (expecting {expected_status})'
         )
コード例 #6
0
async def parse_api_response(resp: ClientResponse):
    """
    Checks for response status, parses the json and checks for API error
    """
    resp.raise_for_status()
    resp = json.loads(await resp.text())
    if "error" in resp:
        raise APIError(resp["error"])
    return resp
コード例 #7
0
 def _raise_error_from_response(
         self,
         resp: aiohttp.ClientResponse,
         ) -> None:
     if resp.status in [401, 403]:
         abort(403, "request rejected by backend")
     if resp.status == 400:
         abort(500, "request rejected by backend")
     if not 200 <= resp.status < 300:
         resp.raise_for_status()
コード例 #8
0
 def raise_for_status(
         resp: aiohttp.ClientResponse) -> aiohttp.ClientResponse:
     """Raise exceptions on failure methods."""
     try:
         resp.raise_for_status()
     except ClientResponseError as err:
         if err.status == HTTP_UNAUTHORIZED:
             raise AuthException(
                 f"Unable to authenticate with API: {err}") from err
         raise ApiException(f"Error from API: {err}") from err
     except ClientError as err:
         raise ApiException(f"Error from API: {err}") from err
     return resp
コード例 #9
0
async def check_error(resp: ClientResponse) -> Any:
    try:
        resp_data = await resp.json()
    except ContentTypeError:
        resp.raise_for_status()
        return
    except json.JSONDecodeError:
        resp.raise_for_status()
        raise

    if not isinstance(resp_data, dict) or "errors" not in resp_data:
        resp.raise_for_status()
        return resp_data

    try:
        error = resp_data["errors"][0]
        code = error["code"]
        message = error["message"]
    except (KeyError, IndexError):
        resp.raise_for_status()
        raise
    if code == 88:
        raise RateLimitError(code, message, resp.headers)
    elif code == 32:
        raise TwitterAuthError(code, message)
    raise TwitterError(code, message)
コード例 #10
0
async def raise_for_status(response: ClientResponse):
    if response.ok:
        return response

    try:
        result = await response.json()
        message = result["message"]
        detail = result["detail"]
        message = f"{message}: {detail}"
    except Exception:
        message = await response.text() or response.reason
        log.exception(message)
    else:
        log.error(message)

    response.raise_for_status()
コード例 #11
0
ファイル: helpers.py プロジェクト: wingsergey/checkbox451_bot
async def raise_for_status(response: ClientResponse):
    if response.ok:
        return response

    try:
        result = await response.json()
    except Exception:
        message = response.reason
        log.exception(message)
    else:
        message = result["message"]
        detail = result.get("detail")
        message = f"{message}" + f": {detail}" if detail else ""
        log.error(message)

    response.raise_for_status()
コード例 #12
0
            async def raise_response_error(resp: aiohttp.ClientResponse,
                                           reason: str):
                # We raise a TransportServerError if the status code is 400 or higher
                # We raise a TransportProtocolError in the other cases

                try:
                    # Raise a ClientResponseError if response status is 400 or higher
                    resp.raise_for_status()
                except ClientResponseError as e:
                    raise TransportServerError(str(e), e.status) from e

                result_text = await resp.text()
                raise TransportProtocolError(
                    f"Server did not return a GraphQL result: "
                    f"{reason}: "
                    f"{result_text}")
コード例 #13
0
async def wrap_and_raise_for_error(response: aiohttp.ClientResponse,
                                   body: Any = None) -> None:
    """Check if the response failed with a non-2XX status code.

    If the response has a non-2XX error code, wrap it in the appropriate
    client exception and re-raise. Otherwise, do nothing.

    Args:
        response: The response to check for a non-OK status.
        body: The data which provides context for the error. If this is
            not specified, the function will attempt to load it from
            response.text(), and fall back to response.reason. Note that this
            behavior is undesirable in some cases, such as for handling streamed
            responses, as calling response.text() will prevent the content from
            being loaded correctly. In such cases, a non-None body must be
            provided.

    Raises:
        SynseError: The response had a non-2XX error code.
    """

    if body is None:
        try:
            body = await response.text()
        except Exception as e:
            log.info('unable to get response text: {}'.format(e))
            body = response.reason

    try:
        response.raise_for_status()
    except aiohttp.ClientResponseError as e:
        log.error(
            f'request to {response.url} responded with {response.status}: {e}')
        error_cls = code_to_err.get(response.status)
        if error_cls is not None:
            try:
                data = json.loads(body)
            except Exception as e:
                log.error(f'failed to parse response JSON: {e}')
                raise error_cls(f'error: {body}') from e
            else:
                raise error_cls(data.get('context')) from e
        raise SynseError from e
コード例 #14
0
async def check_response(response: aiohttp.ClientResponse, ) -> None:
    """
    Check for specialised K8s errors, and raise with extended information.

    Built-in aiohttp's errors only provide the rudimentary titles of the status
    codes, but not the explanation why that error happened. K8s API provides
    this information in the bodies of non-2xx responses. That information can
    replace aiohttp's error messages to be more helpful.

    However, the same error classes are used for now, to meet the expectations
    if some routines in their ``except:`` clauses analysing for specific HTTP
    statuses: e.g. 401 for re-login activities, 404 for patching/deletion, etc.
    """
    if response.status >= 400:
        try:
            payload = await response.json()
        except (json.JSONDecodeError, aiohttp.ContentTypeError,
                aiohttp.ClientConnectionError):
            payload = None

        # Better be safe: who knows which sensitive information can be dumped unless kind==Status.
        if not isinstance(
                payload,
                collections.abc.Mapping) or payload.get('kind') != 'Status':
            payload = None

        # If no information can be retrieved, fall back to the original error.
        if payload is None:
            response.raise_for_status()
        else:
            details = payload.get('details')
            message = payload.get('message') or f"{details}"
            raise APIClientResponseError(response.request_info,
                                         response.history,
                                         status=response.status,
                                         headers=response.headers,
                                         message=message)
コード例 #15
0
 def raise_for_status(result: ClientResponse):
     result.raise_for_status()
コード例 #16
0
ファイル: network.py プロジェクト: alexska777/electrum
 async def default_on_finish(resp: ClientResponse):
     resp.raise_for_status()
     return await resp.text()
コード例 #17
0
async def __get_json_or_raise_for_status(response: ClientResponse):
    try:
        return await response.json()
    except ContentTypeError as e:
        # if no json available in response then use raise_for_status() to raise exception
        response.raise_for_status()
コード例 #18
0
 def raise_for_status(result: ClientResponse):
     # 400 Bad Request status is used by Bitfinex to indicate wrong ticker
     if result.status > 400:
         result.raise_for_status()
コード例 #19
0
 async def __handle(self, resp: ClientResponse) -> dict:
     resp.raise_for_status()
     return await resp.json()