From 8d83d7ac6683577769fe8d1a3bb615bf1be21ced Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Tue, 6 Oct 2020 21:35:15 +0800 Subject: [PATCH] Add exception HTTPError for HTTP 4xx errors --- nvchecker/api.py | 2 +- nvchecker/httpclient/__init__.py | 2 +- nvchecker/httpclient/aiohttp_httpclient.py | 11 +++++++---- nvchecker/httpclient/base.py | 8 ++++++-- nvchecker/httpclient/httpx_httpclient.py | 11 +++++++---- nvchecker/httpclient/tornado_httpclient.py | 11 +++++++---- 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/nvchecker/api.py b/nvchecker/api.py index a05019c..dc31324 100644 --- a/nvchecker/api.py +++ b/nvchecker/api.py @@ -1,7 +1,7 @@ # MIT licensed # Copyright (c) 2020 lilydjwg , et al. -from .httpclient import session, TemporaryError +from .httpclient import session, TemporaryError, HTTPError from .util import ( Entry, BaseWorker, RawResult, VersionResult, AsyncCache, KeyManager, GetVersionError, diff --git a/nvchecker/httpclient/__init__.py b/nvchecker/httpclient/__init__.py index 6c5ae14..3f8cf1e 100644 --- a/nvchecker/httpclient/__init__.py +++ b/nvchecker/httpclient/__init__.py @@ -3,7 +3,7 @@ from typing import Optional -from .base import TemporaryError +from .base import TemporaryError, HTTPError class Proxy: _obj = None diff --git a/nvchecker/httpclient/aiohttp_httpclient.py b/nvchecker/httpclient/aiohttp_httpclient.py index fe538ad..d32dbfd 100644 --- a/nvchecker/httpclient/aiohttp_httpclient.py +++ b/nvchecker/httpclient/aiohttp_httpclient.py @@ -8,7 +8,7 @@ from typing import Optional, Dict import structlog import aiohttp -from .base import BaseSession, TemporaryError, Response +from .base import BaseSession, TemporaryError, Response, HTTPError __all__ = ['session'] @@ -54,10 +54,13 @@ class AiohttpSession(BaseSession): ) as e: raise TemporaryError(599, repr(e), e) + err_cls: Optional[type] = None if res.status >= 500: - raise TemporaryError(res.status, res.reason, res) - else: - res.raise_for_status() + err_cls = TemporaryError + elif res.status >= 400: + err_cls = HTTPError + if err_cls is not None: + raise err_cls(res.status, res.reason, res) body = await res.content.read() return Response(body) diff --git a/nvchecker/httpclient/base.py b/nvchecker/httpclient/base.py index 8115fd4..cd038c8 100644 --- a/nvchecker/httpclient/base.py +++ b/nvchecker/httpclient/base.py @@ -86,10 +86,14 @@ class BaseSession: ''':meta private:''' raise NotImplementedError -class TemporaryError(Exception): - '''A temporary error (e.g. network error) happens.''' +class BaseHTTPError(Exception): def __init__(self, code, message, response): self.code = code self.message = message self.response = response +class TemporaryError(BaseHTTPError): + '''A temporary error (e.g. network error) happens.''' + +class HTTPError(BaseHTTPError): + ''' An HTTP 4xx error happens ''' diff --git a/nvchecker/httpclient/httpx_httpclient.py b/nvchecker/httpclient/httpx_httpclient.py index acfc5e5..4071fa9 100644 --- a/nvchecker/httpclient/httpx_httpclient.py +++ b/nvchecker/httpclient/httpx_httpclient.py @@ -6,7 +6,7 @@ from typing import Dict, Optional import httpx -from .base import BaseSession, TemporaryError, Response +from .base import BaseSession, TemporaryError, Response, HTTPError __all__ = ['session'] @@ -42,14 +42,17 @@ class HttpxSession(BaseSession): headers = headers, params = params, ) + err_cls: Optional[type] = None if r.status_code >= 500: - raise TemporaryError( + err_cls = TemporaryError + elif r.status_code >= 400: + err_cls = HTTPError + if err_cls is not None: + raise err_cls( r.status_code, r.reason_phrase, r, ) - else: - r.raise_for_status() except httpx.TransportError as e: raise TemporaryError(599, repr(e), e) diff --git a/nvchecker/httpclient/tornado_httpclient.py b/nvchecker/httpclient/tornado_httpclient.py index fbd77b3..aeba048 100644 --- a/nvchecker/httpclient/tornado_httpclient.py +++ b/nvchecker/httpclient/tornado_httpclient.py @@ -12,7 +12,7 @@ try: except ImportError: pycurl = None # type: ignore -from .base import BaseSession, TemporaryError, Response +from .base import BaseSession, TemporaryError, Response, HTTPError __all__ = ['session'] @@ -74,12 +74,15 @@ class TornadoSession(BaseSession): r = HTTPRequest(url, **kwargs) res = await AsyncHTTPClient().fetch( r, raise_error=False) + err_cls: Optional[type] = None if res.code >= 500: - raise TemporaryError( + err_cls = TemporaryError + elif res.code >= 400: + err_cls = HTTPError + if err_cls is not None: + raise err_cls( res.code, res.reason, res ) - else: - res.rethrow() return Response(res.body)