Пример #1
0
    async def put(self, url, data, header, auth,
                  timeout) -> Union[ClientBackendResponse, Dict]:
        """
        @See AsyncHTTPClientBackend.put(url, data, header, auth, timeout)
        """
        if isinstance(auth, Dict):
            login = auth.get("username", "")
            password = auth.get("password", "")
            auth_method = (login, password)
        else:
            auth_method = auth

        try:
            async with httpx.AsyncClient() as client:
                response = await client.put(str(url),
                                            data=json.dumps(data),
                                            headers=header,
                                            auth=auth_method,
                                            timeout=timeout)
            return self.prepare_response(response)
        except ConnectTimeout as err:
            # 服务器超时错误
            raise HTTPException(status_code=status_codes.REQUEST_TIMEOUT,
                                detail=str(err))
        except HTTPError as err:
            # 其他类型错误统一使用503代码返回
            raise HTTPException(status_code=status_codes.SERVICE_UNAVAILABLE,
                                detail=str(err))
    def filter_received_response(self, status, response_dict):
        """
        过滤来自远程API服务的相应,统一处理特定的错误
        status - int , 远程API服务HTTP响应的代码,
        response_dict - Dict, 远程API服务HTTP响应内容,在处理远程异常时,此处会获取response_dict中的code字段,
            生成HTTPAPIException

        Exceptions::
            HTTPAPIException,Resource API 调用发生业务性异常或错误时抛出,通常这类错误都会指定Trace_code,用于指定特定的处理逻辑
            HTTPException, Resource API 调用发生异常时抛出,通常这类错误都会指定status_code, 程序可以根据status_code进行处理
        """
        # TODO 按实际API设计Raise相应的异常信息
        if status in [
                status_codes.BAD_REQUEST,
                status_codes.UNAUTHORIZED,
                status_codes.FORBIDDEN,
                status_codes.NOT_FOUND,
                status_codes.CONFLICT,
        ]:
            trace_code = response_dict.get("code", 0)
            # 如果使用了预定义API TradeCode, 使用预定义的detail内容
            if trace_code > 0:
                raise HTTPException(
                    status_code=status,
                    trace_code=trace_code,
                    detail=status_codes.get_reason_phrase(status),
                )
            else:
                raise HTTPException(
                    status_code=status,
                    detail=status_codes.get_reason_phrase(status))
        elif status == status_codes.METHOD_NOT_ALLOWED:
            # HTTPValidationError
            raise HTTPException(status_code=status,
                                detail=status_codes.get_reason_phrase(status))
        elif status == status_codes.UNPROCESSABLE_ENTITY:
            # HTTPValidationError
            raise HTTPException(status_code=status, detail=response_dict)
        elif status in [
                status_codes.OK, status_codes.CREATED, status_codes.ACCEPTED
        ]:
            pass
        else:
            pass
Пример #3
0
def test_exception(setup_module):
    try:
        raise HTTPException(status_code=status_codes.OK, trace_code=111)
    except HTTPException as e:
        assert e.status_code == status_codes.OK
        assert e.trace_code == 111
        assert repr(
            e
        ) == "HTTPException(status_code=<StatuCode.OK: 200>,trace_code=111,detail='OK')"

    try:
        raise HTTPException(status_code=status_codes.OK,
                            trace_code=111,
                            detail="something detail")
    except HTTPException as e:
        assert e.status_code == status_codes.OK
        assert e.trace_code == 111
        assert e.detail == "something detail"
        assert repr(
            e
        ) == "HTTPException(status_code=<StatuCode.OK: 200>,trace_code=111,detail='something detail')"
Пример #4
0
 def mock_prepare_response(self, response):
     # 获得状态代码,不需要等到response收到
     status = response.status_code
     # 服务端50x错误
     if status_codes.is_server_error(status):
         raise HTTPException(status_code=status)
     # 客户端40x错误
     elif status_codes.is_client_error(status):
         pass  # 跳过40x错误,由客户端程序处理
     # 转换为字典格式
     response_dict = cast(Dict[str, Any], response.json())
     # 解码过滤已收到的response
     self.mock_filter_received_response(status, response_dict)
     # 返回组合后的ClientBackendResponse对象
     return ClientBackendResponse(status_code=status,
                                  response=response_dict)