From 579afe012ba6b77979bb776a2fb9983fc819b6ac Mon Sep 17 00:00:00 2001 From: Eli Uriegas Date: Wed, 8 Feb 2017 19:59:34 -0600 Subject: [PATCH] Fixes errors related to #378 --- sanic/exceptions.py | 87 +------------------------------- sanic/sanic.py | 3 +- tests/static/decode me.txt | 2 +- tests/test_exceptions_handler.py | 2 +- tests/test_server_events.py | 3 +- tests/test_static.py | 74 +++++++++++++++------------ 6 files changed, 50 insertions(+), 121 deletions(-) diff --git a/sanic/exceptions.py b/sanic/exceptions.py index 5ba5a090..4f01d64e 100644 --- a/sanic/exceptions.py +++ b/sanic/exceptions.py @@ -97,6 +97,7 @@ INTERNAL_SERVER_ERROR_HTML = ''' class SanicException(Exception): + def __init__(self, message, status_code=None): super().__init__(message) @@ -136,7 +137,7 @@ class RequestTimeout(SanicException): class PayloadTooLarge(SanicException): status_code = 413 - + class HeaderNotFound(SanicException): status_code = 400 @@ -154,87 +155,3 @@ class ContentRangeError(SanicException): class InvalidRangeType(ContentRangeError): pass - - -class Handler: - handlers = None - cached_handlers = None - _missing = object() - - def __init__(self): - self.handlers = [] - self.cached_handlers = {} - self.debug = False - - def _render_traceback_html(self, exception, request): - exc_type, exc_value, tb = sys.exc_info() - frames = extract_tb(tb) - - frame_html = [] - for frame in frames: - frame_html.append(TRACEBACK_LINE_HTML.format(frame)) - - return TRACEBACK_WRAPPER_HTML.format( - style=TRACEBACK_STYLE, - exc_name=exc_type.__name__, - exc_value=exc_value, - frame_html=''.join(frame_html), - uri=request.url) - - def add(self, exception, handler): - self.handlers.append((exception, handler)) - - def lookup(self, exception): - handler = self.cached_handlers.get(exception, self._missing) - if handler is self._missing: - for exception_class, handler in self.handlers: - if isinstance(exception, exception_class): - self.cached_handlers[type(exception)] = handler - return handler - self.cached_handlers[type(exception)] = None - handler = None - return handler - - def response(self, request, exception): - """ - Fetches and executes an exception handler and returns a response object - - :param request: Request - :param exception: Exception to handle - :return: Response object - """ - handler = self.lookup(exception) - try: - response = handler and handler( - request=request, exception=exception) - if response is None: - response = self.default(request=request, exception=exception) - except: - log.error(format_exc()) - if self.debug: - response_message = ( - 'Exception raised in exception handler "{}" ' - 'for uri: "{}"\n{}').format( - handler.__name__, request.url, format_exc()) - log.error(response_message) - return text(response_message, 500) - else: - return text('An error occurred while handling an error', 500) - return response - - def default(self, request, exception): - log.error(format_exc()) - if isinstance(exception, SanicException): - return text( - 'Error: {}'.format(exception), - status=getattr(exception, 'status_code', 500)) - elif self.debug: - html_output = self._render_traceback_html(exception, request) - - response_message = ( - 'Exception occurred while handling uri: "{}"\n{}'.format( - request.url, format_exc())) - log.error(response_message) - return html(html_output, status=500) - else: - return html(INTERNAL_SERVER_ERROR_HTML, status=500) diff --git a/sanic/sanic.py b/sanic/sanic.py index f4175b58..951632be 100644 --- a/sanic/sanic.py +++ b/sanic/sanic.py @@ -10,7 +10,8 @@ from urllib.parse import urlencode, urlunparse from .config import Config from .constants import HTTP_METHODS -from .exceptions import Handler, ServerError, URLBuildError +from .handlers import ErrorHandler +from .exceptions import ServerError, URLBuildError from .log import log from .response import HTTPResponse from .router import Router diff --git a/tests/static/decode me.txt b/tests/static/decode me.txt index e5d05ac1..b1c36682 100644 --- a/tests/static/decode me.txt +++ b/tests/static/decode me.txt @@ -1 +1 @@ -I need to be decoded as a uri +I am just a regular static file that needs to have its uri decoded diff --git a/tests/test_exceptions_handler.py b/tests/test_exceptions_handler.py index d11f7380..e252d3e6 100644 --- a/tests/test_exceptions_handler.py +++ b/tests/test_exceptions_handler.py @@ -31,7 +31,7 @@ def handler_4(request): @exception_handler_app.route('/5') def handler_5(request): class CustomServerError(ServerError): - pass + status_code=200 raise CustomServerError('Custom server error') diff --git a/tests/test_server_events.py b/tests/test_server_events.py index 27a5af29..fce98440 100644 --- a/tests/test_server_events.py +++ b/tests/test_server_events.py @@ -6,6 +6,7 @@ import signal import pytest from sanic import Sanic +from sanic.utils import HOST, PORT AVAILABLE_LISTENERS = [ 'before_start', @@ -30,7 +31,7 @@ def start_stop_app(random_name_app, **run_kwargs): signal.signal(signal.SIGALRM, stop_on_alarm) signal.alarm(1) try: - random_name_app.run(**run_kwargs) + random_name_app.run(HOST, PORT, **run_kwargs) except KeyboardInterrupt: pass diff --git a/tests/test_static.py b/tests/test_static.py index 32ea786f..4d6c0ee2 100644 --- a/tests/test_static.py +++ b/tests/test_static.py @@ -49,12 +49,12 @@ def test_static_directory(file_name, base_uri, static_file_directory): assert response.status == 200 assert response.body == get_file_content(static_file_directory, file_name) + @pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) -def test_static_head_request( - file_name, static_file_content, static_file_directory): +def test_static_head_request(file_name, static_file_directory): app = Sanic('test_static') app.static( - '/testing.file', get_file_path(static_file_directory, file_name), + '/testing.file', get_file_path(static_file_directory, file_name), use_content_range=True) request, response = sanic_endpoint_test( @@ -62,14 +62,16 @@ def test_static_head_request( assert response.status == 200 assert 'Accept-Ranges' in response.headers assert 'Content-Length' in response.headers - assert int(response.headers['Content-Length']) == len(get_file_content(static_file_directory, file_name)) + assert int(response.headers[ + 'Content-Length']) == len( + get_file_content(static_file_directory, file_name)) + @pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) -def test_static_content_range_correct( - file_name, static_file_content, static_file_directory): +def test_static_content_range_correct(file_name, static_file_directory): app = Sanic('test_static') app.static( - '/testing.file', get_file_path(static_file_directory, file_name), + '/testing.file', get_file_path(static_file_directory, file_name), use_content_range=True) headers = { @@ -80,16 +82,18 @@ def test_static_content_range_correct( assert response.status == 200 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers - static_content = bytes(get_file_content(static_file_directory, file_name))[12:19] - assert int(response.headers['Content-Length']) == len(get_file_content(static_file_directory, file_name)) - assert response.body == get_file_content(static_file_directory, file_name) + static_content = bytes(get_file_content( + static_file_directory, file_name))[12:19] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + @pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) -def test_static_content_range_front( - file_name, static_file_content, static_file_directory): +def test_static_content_range_front(file_name, static_file_directory): app = Sanic('test_static') app.static( - '/testing.file', get_file_path(static_file_directory, file_name), + '/testing.file', get_file_path(static_file_directory, file_name), use_content_range=True) headers = { @@ -100,19 +104,20 @@ def test_static_content_range_front( assert response.status == 200 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers - static_content = bytes(get_file_content(static_file_directory, file_name))[12:] - assert int(response.headers['Content-Length']) == len(get_file_content(static_file_directory, file_name)) - assert response.body == get_file_content(static_file_directory, file_name) + static_content = bytes(get_file_content( + static_file_directory, file_name))[12:] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + - @pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) -def test_static_content_range_back( - file_name, static_file_content, static_file_directory): +def test_static_content_range_back(file_name, static_file_directory): app = Sanic('test_static') app.static( - '/testing.file', get_file_path(static_file_directory, file_name), + '/testing.file', get_file_path(static_file_directory, file_name), use_content_range=True) - + headers = { 'Range': 'bytes=-12' } @@ -121,30 +126,35 @@ def test_static_content_range_back( assert response.status == 200 assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers - static_content = bytes(get_file_content(static_file_directory, file_name))[-12:] - assert int(response.headers['Content-Length']) == len(get_file_content(static_file_directory, file_name)) - assert response.body == get_file_content(static_file_directory, file_name) + static_content = bytes(get_file_content( + static_file_directory, file_name))[-12:] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + @pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) -def test_static_content_range_empty( - file_name, static_file_content, static_file_directory): +def test_static_content_range_empty(file_name, static_file_directory): app = Sanic('test_static') app.static( - '/testing.file', get_file_path(static_file_directory, file_name), + '/testing.file', get_file_path(static_file_directory, file_name), use_content_range=True) request, response = sanic_endpoint_test(app, uri='/testing.file') assert response.status == 200 assert 'Content-Length' in response.headers assert 'Content-Range' not in response.headers - assert int(response.headers['Content-Length']) == len(get_file_content(static_file_directory, file_name)) - assert response.body == bytes(get_file_content(static_file_directory, file_name)) + assert int(response.headers[ + 'Content-Length']) == len(get_file_content(static_file_directory, file_name)) + assert response.body == bytes( + get_file_content(static_file_directory, file_name)) + @pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) -def test_static_content_range_error(static_file_path, static_file_content): +def test_static_content_range_error(file_name, static_file_directory): app = Sanic('test_static') app.static( - '/testing.file', get_file_path(static_file_directory, file_name), + '/testing.file', get_file_path(static_file_directory, file_name), use_content_range=True) headers = { @@ -156,4 +166,4 @@ def test_static_content_range_error(static_file_path, static_file_content): assert 'Content-Length' in response.headers assert 'Content-Range' in response.headers assert response.headers['Content-Range'] == "bytes */%s" % ( - len(static_file_content),) + len(get_file_content(static_file_directory, file_name)),)