refactor: consistent exception naming (#2420)
Co-authored-by: Adam Hopkins <adam@amhopkins.com>
This commit is contained in:
parent
2bfa65e0de
commit
86ae5f981c
|
@ -58,7 +58,7 @@ from sanic.blueprints import Blueprint
|
|||
from sanic.compat import OS_IS_WINDOWS, enable_windows_color_support
|
||||
from sanic.config import SANIC_PREFIX, Config
|
||||
from sanic.exceptions import (
|
||||
InvalidUsage,
|
||||
BadRequest,
|
||||
SanicException,
|
||||
ServerError,
|
||||
URLBuildError,
|
||||
|
@ -281,7 +281,7 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
|
|||
valid = ", ".join(
|
||||
map(lambda x: x.lower(), ListenerEvent.__members__.keys())
|
||||
)
|
||||
raise InvalidUsage(f"Invalid event: {event}. Use one of: {valid}")
|
||||
raise BadRequest(f"Invalid event: {event}. Use one of: {valid}")
|
||||
|
||||
if "." in _event:
|
||||
self.signal(_event.value)(
|
||||
|
|
|
@ -19,7 +19,7 @@ import typing as t
|
|||
from functools import partial
|
||||
from traceback import extract_tb
|
||||
|
||||
from sanic.exceptions import InvalidUsage, SanicException
|
||||
from sanic.exceptions import BadRequest, SanicException
|
||||
from sanic.helpers import STATUS_CODES
|
||||
from sanic.request import Request
|
||||
from sanic.response import HTTPResponse, html, json, text
|
||||
|
@ -506,7 +506,7 @@ def exception_response(
|
|||
# $ curl localhost:8000 -d '{"foo": "bar"}'
|
||||
# And provide them with JSONRenderer
|
||||
renderer = JSONRenderer if request.json else base
|
||||
except InvalidUsage:
|
||||
except BadRequest:
|
||||
renderer = base
|
||||
else:
|
||||
renderer = RENDERERS_BY_CONFIG.get(render_format, renderer)
|
||||
|
|
|
@ -42,7 +42,7 @@ class NotFound(SanicException):
|
|||
quiet = True
|
||||
|
||||
|
||||
class InvalidUsage(SanicException):
|
||||
class BadRequest(SanicException):
|
||||
"""
|
||||
**Status**: 400 Bad Request
|
||||
"""
|
||||
|
@ -51,11 +51,14 @@ class InvalidUsage(SanicException):
|
|||
quiet = True
|
||||
|
||||
|
||||
class BadURL(InvalidUsage):
|
||||
InvalidUsage = BadRequest
|
||||
|
||||
|
||||
class BadURL(BadRequest):
|
||||
...
|
||||
|
||||
|
||||
class MethodNotSupported(SanicException):
|
||||
class MethodNotAllowed(SanicException):
|
||||
"""
|
||||
**Status**: 405 Method Not Allowed
|
||||
"""
|
||||
|
@ -68,6 +71,9 @@ class MethodNotSupported(SanicException):
|
|||
self.headers = {"Allow": ", ".join(allowed_methods)}
|
||||
|
||||
|
||||
MethodNotSupported = MethodNotAllowed
|
||||
|
||||
|
||||
class ServerError(SanicException):
|
||||
"""
|
||||
**Status**: 500 Internal Server Error
|
||||
|
@ -129,19 +135,19 @@ class PayloadTooLarge(SanicException):
|
|||
quiet = True
|
||||
|
||||
|
||||
class HeaderNotFound(InvalidUsage):
|
||||
class HeaderNotFound(BadRequest):
|
||||
"""
|
||||
**Status**: 400 Bad Request
|
||||
"""
|
||||
|
||||
|
||||
class InvalidHeader(InvalidUsage):
|
||||
class InvalidHeader(BadRequest):
|
||||
"""
|
||||
**Status**: 400 Bad Request
|
||||
"""
|
||||
|
||||
|
||||
class ContentRangeError(SanicException):
|
||||
class RangeNotSatisfiable(SanicException):
|
||||
"""
|
||||
**Status**: 416 Range Not Satisfiable
|
||||
"""
|
||||
|
@ -154,7 +160,10 @@ class ContentRangeError(SanicException):
|
|||
self.headers = {"Content-Range": f"bytes */{content_range.total}"}
|
||||
|
||||
|
||||
class HeaderExpectationFailed(SanicException):
|
||||
ContentRangeError = RangeNotSatisfiable
|
||||
|
||||
|
||||
class ExpectationFailed(SanicException):
|
||||
"""
|
||||
**Status**: 417 Expectation Failed
|
||||
"""
|
||||
|
@ -163,6 +172,9 @@ class HeaderExpectationFailed(SanicException):
|
|||
quiet = True
|
||||
|
||||
|
||||
HeaderExpectationFailed = ExpectationFailed
|
||||
|
||||
|
||||
class Forbidden(SanicException):
|
||||
"""
|
||||
**Status**: 403 Forbidden
|
||||
|
@ -172,7 +184,7 @@ class Forbidden(SanicException):
|
|||
quiet = True
|
||||
|
||||
|
||||
class InvalidRangeType(ContentRangeError):
|
||||
class InvalidRangeType(RangeNotSatisfiable):
|
||||
"""
|
||||
**Status**: 416 Range Not Satisfiable
|
||||
"""
|
||||
|
|
|
@ -10,9 +10,9 @@ from sanic.errorpages import (
|
|||
exception_response,
|
||||
)
|
||||
from sanic.exceptions import (
|
||||
ContentRangeError,
|
||||
HeaderNotFound,
|
||||
InvalidRangeType,
|
||||
RangeNotSatisfiable,
|
||||
SanicException,
|
||||
)
|
||||
from sanic.helpers import Default, _default
|
||||
|
@ -296,18 +296,18 @@ class ContentRangeHandler:
|
|||
try:
|
||||
self.start = int(start_b) if start_b else None
|
||||
except ValueError:
|
||||
raise ContentRangeError(
|
||||
raise RangeNotSatisfiable(
|
||||
"'%s' is invalid for Content Range" % (start_b,), self
|
||||
)
|
||||
try:
|
||||
self.end = int(end_b) if end_b else None
|
||||
except ValueError:
|
||||
raise ContentRangeError(
|
||||
raise RangeNotSatisfiable(
|
||||
"'%s' is invalid for Content Range" % (end_b,), self
|
||||
)
|
||||
if self.end is None:
|
||||
if self.start is None:
|
||||
raise ContentRangeError(
|
||||
raise RangeNotSatisfiable(
|
||||
"Invalid for Content Range parameters", self
|
||||
)
|
||||
else:
|
||||
|
@ -319,7 +319,7 @@ class ContentRangeHandler:
|
|||
self.start = self.total - self.end
|
||||
self.end = self.total - 1
|
||||
if self.start >= self.end:
|
||||
raise ContentRangeError(
|
||||
raise RangeNotSatisfiable(
|
||||
"Invalid for Content Range parameters", self
|
||||
)
|
||||
self.size = self.end - self.start + 1
|
||||
|
|
|
@ -12,8 +12,8 @@ from enum import Enum
|
|||
|
||||
from sanic.compat import Header
|
||||
from sanic.exceptions import (
|
||||
HeaderExpectationFailed,
|
||||
InvalidUsage,
|
||||
BadRequest,
|
||||
ExpectationFailed,
|
||||
PayloadTooLarge,
|
||||
ServerError,
|
||||
ServiceUnavailable,
|
||||
|
@ -53,14 +53,14 @@ class Http(metaclass=TouchUpMeta):
|
|||
:raises ServerError:
|
||||
:raises PayloadTooLarge:
|
||||
:raises Exception:
|
||||
:raises InvalidUsage:
|
||||
:raises HeaderExpectationFailed:
|
||||
:raises BadRequest:
|
||||
:raises ExpectationFailed:
|
||||
:raises RuntimeError:
|
||||
:raises ServerError:
|
||||
:raises ServerError:
|
||||
:raises InvalidUsage:
|
||||
:raises InvalidUsage:
|
||||
:raises InvalidUsage:
|
||||
:raises BadRequest:
|
||||
:raises BadRequest:
|
||||
:raises BadRequest:
|
||||
:raises PayloadTooLarge:
|
||||
:raises RuntimeError:
|
||||
"""
|
||||
|
@ -248,7 +248,7 @@ class Http(metaclass=TouchUpMeta):
|
|||
|
||||
headers.append(h)
|
||||
except Exception:
|
||||
raise InvalidUsage("Bad Request")
|
||||
raise BadRequest("Bad Request")
|
||||
|
||||
headers_instance = Header(headers)
|
||||
self.upgrade_websocket = (
|
||||
|
@ -281,7 +281,7 @@ class Http(metaclass=TouchUpMeta):
|
|||
if expect.lower() == "100-continue":
|
||||
self.expecting_continue = True
|
||||
else:
|
||||
raise HeaderExpectationFailed(f"Unknown Expect: {expect}")
|
||||
raise ExpectationFailed(f"Unknown Expect: {expect}")
|
||||
|
||||
if headers.getone("transfer-encoding", None) == "chunked":
|
||||
self.request_body = "chunked"
|
||||
|
@ -510,7 +510,7 @@ class Http(metaclass=TouchUpMeta):
|
|||
|
||||
if len(buf) > 64:
|
||||
self.keep_alive = False
|
||||
raise InvalidUsage("Bad chunked encoding")
|
||||
raise BadRequest("Bad chunked encoding")
|
||||
|
||||
await self._receive_more()
|
||||
|
||||
|
@ -518,14 +518,14 @@ class Http(metaclass=TouchUpMeta):
|
|||
size = int(buf[2:pos].split(b";", 1)[0].decode(), 16)
|
||||
except Exception:
|
||||
self.keep_alive = False
|
||||
raise InvalidUsage("Bad chunked encoding")
|
||||
raise BadRequest("Bad chunked encoding")
|
||||
|
||||
if size <= 0:
|
||||
self.request_body = None
|
||||
|
||||
if size < 0:
|
||||
self.keep_alive = False
|
||||
raise InvalidUsage("Bad chunked encoding")
|
||||
raise BadRequest("Bad chunked encoding")
|
||||
|
||||
# Consume CRLF, chunk size 0 and the two CRLF that follow
|
||||
pos += 4
|
||||
|
|
|
@ -3,7 +3,7 @@ from functools import partial
|
|||
from typing import Callable, List, Optional, Union, overload
|
||||
|
||||
from sanic.base.meta import SanicMeta
|
||||
from sanic.exceptions import InvalidUsage
|
||||
from sanic.exceptions import BadRequest
|
||||
from sanic.models.futures import FutureListener
|
||||
from sanic.models.handler_types import ListenerType, Sanic
|
||||
|
||||
|
@ -86,7 +86,7 @@ class ListenerMixin(metaclass=SanicMeta):
|
|||
|
||||
if callable(listener_or_event):
|
||||
if event_or_none is None:
|
||||
raise InvalidUsage(
|
||||
raise BadRequest(
|
||||
"Invalid event registration: Missing event name."
|
||||
)
|
||||
return register_listener(listener_or_event, event_or_none)
|
||||
|
|
|
@ -18,10 +18,10 @@ from sanic.compat import stat_async
|
|||
from sanic.constants import DEFAULT_HTTP_CONTENT_TYPE, HTTP_METHODS
|
||||
from sanic.errorpages import RESPONSE_MAPPING
|
||||
from sanic.exceptions import (
|
||||
ContentRangeError,
|
||||
BadRequest,
|
||||
FileNotFound,
|
||||
HeaderNotFound,
|
||||
InvalidUsage,
|
||||
RangeNotSatisfiable,
|
||||
)
|
||||
from sanic.handlers import ContentRangeHandler
|
||||
from sanic.log import deprecation, error_logger
|
||||
|
@ -778,7 +778,7 @@ class RouteMixin(metaclass=SanicMeta):
|
|||
# Using this to determine if the URL is trying to break out of the path
|
||||
# served. os.path.realpath seems to be very slow
|
||||
if __file_uri__ and "../" in __file_uri__:
|
||||
raise InvalidUsage("Invalid URL")
|
||||
raise BadRequest("Invalid URL")
|
||||
# Merge served directory and requested file if provided
|
||||
# Strip all / that in the beginning of the URL to help prevent python
|
||||
# from herping a derp and treating the uri as an absolute path
|
||||
|
@ -865,7 +865,7 @@ class RouteMixin(metaclass=SanicMeta):
|
|||
file_path, headers=headers, _range=_range
|
||||
)
|
||||
return await file(file_path, headers=headers, _range=_range)
|
||||
except ContentRangeError:
|
||||
except RangeNotSatisfiable:
|
||||
raise
|
||||
except FileNotFoundError:
|
||||
raise FileNotFound(
|
||||
|
|
|
@ -3,7 +3,7 @@ import sys
|
|||
|
||||
from typing import Any, Awaitable, Callable, MutableMapping, Optional, Union
|
||||
|
||||
from sanic.exceptions import InvalidUsage
|
||||
from sanic.exceptions import BadRequest
|
||||
from sanic.server.websockets.connection import WebSocketConnection
|
||||
|
||||
|
||||
|
@ -84,7 +84,7 @@ class MockTransport: # no cov
|
|||
try:
|
||||
return self._websocket_connection
|
||||
except AttributeError:
|
||||
raise InvalidUsage("Improper websocket connection.")
|
||||
raise BadRequest("Improper websocket connection.")
|
||||
|
||||
def create_websocket_connection(
|
||||
self, send: ASGISend, receive: ASGIReceive
|
||||
|
|
|
@ -35,7 +35,7 @@ from httptools.parser.errors import HttpParserInvalidURLError # type: ignore
|
|||
|
||||
from sanic.compat import CancelledErrors, Header
|
||||
from sanic.constants import DEFAULT_HTTP_CONTENT_TYPE
|
||||
from sanic.exceptions import BadURL, InvalidUsage, ServerError
|
||||
from sanic.exceptions import BadRequest, BadURL, ServerError
|
||||
from sanic.headers import (
|
||||
AcceptContainer,
|
||||
Options,
|
||||
|
@ -379,7 +379,7 @@ class Request:
|
|||
except Exception:
|
||||
if not self.body:
|
||||
return None
|
||||
raise InvalidUsage("Failed when parsing body as json")
|
||||
raise BadRequest("Failed when parsing body as json")
|
||||
|
||||
return self.parsed_json
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from sanic_routing.route import Route # type: ignore
|
|||
|
||||
from sanic.constants import HTTP_METHODS
|
||||
from sanic.errorpages import check_error_format
|
||||
from sanic.exceptions import MethodNotSupported, NotFound, SanicException
|
||||
from sanic.exceptions import MethodNotAllowed, NotFound, SanicException
|
||||
from sanic.models.handler_types import RouteHandler
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ class Router(BaseRouter):
|
|||
except RoutingNotFound as e:
|
||||
raise NotFound("Requested URL {} not found".format(e.path))
|
||||
except NoMethod as e:
|
||||
raise MethodNotSupported(
|
||||
raise MethodNotAllowed(
|
||||
"Method {} not allowed for URL {}".format(method, path),
|
||||
method=method,
|
||||
allowed_methods=e.allowed_methods,
|
||||
|
|
|
@ -9,7 +9,7 @@ import uvicorn
|
|||
from sanic import Sanic
|
||||
from sanic.application.state import Mode
|
||||
from sanic.asgi import MockTransport
|
||||
from sanic.exceptions import Forbidden, InvalidUsage, ServiceUnavailable
|
||||
from sanic.exceptions import Forbidden, BadRequest, ServiceUnavailable
|
||||
from sanic.request import Request
|
||||
from sanic.response import json, text
|
||||
from sanic.server.websockets.connection import WebSocketConnection
|
||||
|
@ -392,7 +392,7 @@ async def test_websocket_accept_with_multiple_subprotocols(
|
|||
|
||||
|
||||
def test_improper_websocket_connection(transport, send, receive):
|
||||
with pytest.raises(InvalidUsage):
|
||||
with pytest.raises(BadRequest):
|
||||
transport.get_websocket_connection()
|
||||
|
||||
transport.create_websocket_connection(send, receive)
|
||||
|
|
|
@ -5,7 +5,7 @@ from sanic.blueprint_group import BlueprintGroup
|
|||
from sanic.blueprints import Blueprint
|
||||
from sanic.exceptions import (
|
||||
Forbidden,
|
||||
InvalidUsage,
|
||||
BadRequest,
|
||||
SanicException,
|
||||
ServerError,
|
||||
)
|
||||
|
@ -104,7 +104,7 @@ def test_bp_group(app: Sanic):
|
|||
|
||||
@blueprint_1.route("/invalid")
|
||||
def blueprint_1_error(request: Request):
|
||||
raise InvalidUsage("Invalid")
|
||||
raise BadRequest("Invalid")
|
||||
|
||||
@blueprint_2.route("/")
|
||||
def blueprint_2_default_route(request):
|
||||
|
@ -120,7 +120,7 @@ def test_bp_group(app: Sanic):
|
|||
|
||||
blueprint_3 = Blueprint("blueprint_3", url_prefix="/bp3")
|
||||
|
||||
@blueprint_group_1.exception(InvalidUsage)
|
||||
@blueprint_group_1.exception(BadRequest)
|
||||
def handle_group_exception(request, exception):
|
||||
return text("BP1_ERR_OK")
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ from sanic.app import Sanic
|
|||
from sanic.blueprints import Blueprint
|
||||
from sanic.constants import HTTP_METHODS
|
||||
from sanic.exceptions import (
|
||||
InvalidUsage,
|
||||
BadRequest,
|
||||
NotFound,
|
||||
SanicException,
|
||||
ServerError,
|
||||
|
@ -448,7 +448,7 @@ def test_bp_exception_handler(app):
|
|||
|
||||
@blueprint.route("/1")
|
||||
def handler_1(request):
|
||||
raise InvalidUsage("OK")
|
||||
raise BadRequest("OK")
|
||||
|
||||
@blueprint.route("/2")
|
||||
def handler_2(request):
|
||||
|
|
|
@ -6,9 +6,16 @@ from bs4 import BeautifulSoup
|
|||
|
||||
from sanic import Sanic
|
||||
from sanic.exceptions import (
|
||||
BadRequest,
|
||||
ContentRangeError,
|
||||
ExpectationFailed,
|
||||
Forbidden,
|
||||
HeaderExpectationFailed,
|
||||
InvalidUsage,
|
||||
MethodNotAllowed,
|
||||
MethodNotSupported,
|
||||
NotFound,
|
||||
RangeNotSatisfiable,
|
||||
SanicException,
|
||||
ServerError,
|
||||
Unauthorized,
|
||||
|
@ -77,7 +84,7 @@ def exception_app():
|
|||
|
||||
@app.route("/invalid")
|
||||
def handler_invalid(request):
|
||||
raise InvalidUsage("OK")
|
||||
raise BadRequest("OK")
|
||||
|
||||
@app.route("/abort/401")
|
||||
def handler_401_error(request):
|
||||
|
@ -136,7 +143,7 @@ def test_server_error_exception(exception_app):
|
|||
|
||||
|
||||
def test_invalid_usage_exception(exception_app):
|
||||
"""Test the built-in InvalidUsage exception works"""
|
||||
"""Test the built-in BadRequest exception works"""
|
||||
request, response = exception_app.test_client.get("/invalid")
|
||||
assert response.status == 400
|
||||
|
||||
|
@ -375,3 +382,10 @@ def test_contextual_exception_functional_message(override):
|
|||
assert response.status == 418
|
||||
assert response.json["message"] == error_message
|
||||
assert response.json["context"] == {"foo": "bar"}
|
||||
|
||||
|
||||
def test_exception_aliases():
|
||||
assert InvalidUsage is BadRequest
|
||||
assert MethodNotSupported is MethodNotAllowed
|
||||
assert ContentRangeError is RangeNotSatisfiable
|
||||
assert HeaderExpectationFailed is ExpectationFailed
|
||||
|
|
|
@ -10,7 +10,7 @@ from bs4 import BeautifulSoup
|
|||
from pytest import LogCaptureFixture, MonkeyPatch
|
||||
|
||||
from sanic import Sanic, handlers
|
||||
from sanic.exceptions import Forbidden, InvalidUsage, NotFound, ServerError
|
||||
from sanic.exceptions import Forbidden, BadRequest, NotFound, ServerError
|
||||
from sanic.handlers import ErrorHandler
|
||||
from sanic.request import Request
|
||||
from sanic.response import stream, text
|
||||
|
@ -32,7 +32,7 @@ def exception_handler_app():
|
|||
|
||||
@exception_handler_app.route("/1", error_format="html")
|
||||
def handler_1(request):
|
||||
raise InvalidUsage("OK")
|
||||
raise BadRequest("OK")
|
||||
|
||||
@exception_handler_app.route("/2", error_format="html")
|
||||
def handler_2(request):
|
||||
|
|
|
@ -8,7 +8,7 @@ import pytest
|
|||
|
||||
from sanic_testing.testing import HOST, PORT
|
||||
|
||||
from sanic.exceptions import InvalidUsage, SanicException
|
||||
from sanic.exceptions import BadRequest, SanicException
|
||||
|
||||
|
||||
AVAILABLE_LISTENERS = [
|
||||
|
@ -137,7 +137,7 @@ async def test_trigger_before_events_create_server_missing_event(app):
|
|||
class MySanicDb:
|
||||
pass
|
||||
|
||||
with pytest.raises(InvalidUsage):
|
||||
with pytest.raises(BadRequest):
|
||||
|
||||
@app.listener
|
||||
async def init_db(app, loop):
|
||||
|
|
|
@ -11,7 +11,7 @@ import pytest
|
|||
from sanic_testing.testing import HOST, PORT
|
||||
|
||||
from sanic.compat import ctrlc_workaround_for_windows
|
||||
from sanic.exceptions import InvalidUsage
|
||||
from sanic.exceptions import BadRequest
|
||||
from sanic.response import HTTPResponse
|
||||
|
||||
|
||||
|
@ -122,6 +122,6 @@ def test_signals_with_invalid_invocation(app):
|
|||
return HTTPResponse()
|
||||
|
||||
with pytest.raises(
|
||||
InvalidUsage, match="Invalid event registration: Missing event name"
|
||||
BadRequest, match="Invalid event registration: Missing event name"
|
||||
):
|
||||
app.listener(stop)
|
||||
|
|
|
@ -2,7 +2,6 @@ import pytest
|
|||
|
||||
from sanic.blueprints import Blueprint
|
||||
from sanic.constants import HTTP_METHODS
|
||||
from sanic.exceptions import InvalidUsage
|
||||
from sanic.request import Request
|
||||
from sanic.response import HTTPResponse, text
|
||||
from sanic.views import HTTPMethodView
|
||||
|
|
Loading…
Reference in New Issue
Block a user