Merge pull request #29 from huge-success/master

merge upstream master branch
This commit is contained in:
7 2018-10-13 17:28:32 -07:00 committed by GitHub
commit 9ae6dfb6d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 22 deletions

View File

@ -41,4 +41,4 @@ if __name__ == "__main__":
" Example Module: project.sanic_server.app" " Example Module: project.sanic_server.app"
.format(e.name)) .format(e.name))
except ValueError as e: except ValueError as e:
logger.error("{}".format(e)) logger.exception("Failed to run app")

View File

@ -1,5 +1,5 @@
import sys import sys
from traceback import format_exc, extract_tb from traceback import extract_tb, format_exc
from sanic.exceptions import ( from sanic.exceptions import (
ContentRangeError, ContentRangeError,
@ -84,28 +84,35 @@ class ErrorHandler:
response = self.default(request, exception) response = self.default(request, exception)
except Exception: except Exception:
self.log(format_exc()) self.log(format_exc())
if self.debug: try:
url = getattr(request, 'url', 'unknown') url = repr(request.url)
except AttributeError:
url = "unknown"
response_message = ('Exception raised in exception handler ' response_message = ('Exception raised in exception handler '
'"%s" for uri: "%s"\n%s') '"%s" for uri: %s')
logger.error(response_message, logger.exception(response_message, handler.__name__, url)
handler.__name__, url, format_exc())
return text(response_message % ( if self.debug:
handler.__name__, url, format_exc()), 500) return text(response_message % (handler.__name__, url), 500)
else: else:
return text('An error occurred while handling an error', 500) return text('An error occurred while handling an error', 500)
return response return response
def log(self, message, level='error'): def log(self, message, level='error'):
""" """
Override this method in an ErrorHandler subclass to prevent Deprecated, do not use.
logging exceptions.
""" """
getattr(logger, level)(message)
def default(self, request, exception): def default(self, request, exception):
self.log(format_exc()) self.log(format_exc())
try:
url = repr(request.url)
except AttributeError:
url = "unknown"
response_message = ('Exception occurred while handling uri: %s')
logger.exception(response_message, url)
if issubclass(type(exception), SanicException): if issubclass(type(exception), SanicException):
return text( return text(
'Error: {}'.format(exception), 'Error: {}'.format(exception),
@ -115,9 +122,6 @@ class ErrorHandler:
elif self.debug: elif self.debug:
html_output = self._render_traceback_html(exception, request) html_output = self._render_traceback_html(exception, request)
response_message = ('Exception occurred while handling uri: '
'"%s"\n%s')
logger.error(response_message, request.url, format_exc())
return html(html_output, status=500) return html(html_output, status=500)
else: else:
return html(INTERNAL_SERVER_ERROR_HTML, status=500) return html(INTERNAL_SERVER_ERROR_HTML, status=500)

View File

@ -58,6 +58,6 @@ LOGGING_CONFIG_DEFAULTS = dict(
) )
logger = logging.getLogger('root') logger = logging.getLogger('sanic.root')
error_logger = logging.getLogger('sanic.error') error_logger = logging.getLogger('sanic.error')
access_logger = logging.getLogger('sanic.access') access_logger = logging.getLogger('sanic.access')

View File

@ -38,6 +38,10 @@ class RouteDoesNotExist(Exception):
pass pass
class ParameterNameConflicts(Exception):
pass
class Router: class Router:
"""Router supports basic routing with parameters and method checks """Router supports basic routing with parameters and method checks
@ -195,12 +199,19 @@ class Router:
methods = frozenset(methods) methods = frozenset(methods)
parameters = [] parameters = []
parameter_names = set()
properties = {"unhashable": None} properties = {"unhashable": None}
def add_parameter(match): def add_parameter(match):
name = match.group(1) name = match.group(1)
name, _type, pattern = self.parse_parameter_string(name) name, _type, pattern = self.parse_parameter_string(name)
if name in parameter_names:
raise ParameterNameConflicts(
"Multiple parameter named <{name}> "
"in route uri {uri}".format(name=name, uri=uri))
parameter_names.add(name)
parameter = Parameter( parameter = Parameter(
name=name, cast=_type) name=name, cast=_type)
parameters.append(parameter) parameters.append(parameter)

View File

@ -436,7 +436,7 @@ class HttpProtocol(asyncio.Protocol):
logger.error("Transport closed @ %s and exception " logger.error("Transport closed @ %s and exception "
"experienced during error handling", "experienced during error handling",
self.transport.get_extra_info('peername')) self.transport.get_extra_info('peername'))
logger.debug('Exception:\n%s', traceback.format_exc()) logger.debug('Exception:', exc_info=True)
else: else:
self.write_error(ServerError(message)) self.write_error(ServerError(message))
logger.error(message) logger.error(message)

View File

@ -1,4 +1,3 @@
import traceback
from json import JSONDecodeError from json import JSONDecodeError
from sanic.log import logger from sanic.log import logger
from sanic.exceptions import MethodNotSupported from sanic.exceptions import MethodNotSupported
@ -73,8 +72,7 @@ class SanicTestClient:
**request_kwargs) **request_kwargs)
results[-1] = response results[-1] = response
except Exception as e: except Exception as e:
logger.error( logger.exception('Exception')
'Exception:\n{}'.format(traceback.format_exc()))
exceptions.append(e) exceptions.append(e)
self.app.stop() self.app.stop()

View File

@ -48,6 +48,7 @@ setup_kwargs = {
'License :: OSI Approved :: MIT License', 'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
], ],
} }

View File

@ -3,7 +3,7 @@ import pytest
from sanic import Sanic from sanic import Sanic
from sanic.response import text, json from sanic.response import text, json
from sanic.router import RouteExists, RouteDoesNotExist from sanic.router import RouteExists, RouteDoesNotExist, ParameterNameConflicts
from sanic.constants import HTTP_METHODS from sanic.constants import HTTP_METHODS
@ -935,3 +935,10 @@ def test_uri_with_different_method_and_different_params(app):
assert response.json == { assert response.json == {
'action': 'post' 'action': 'post'
} }
def test_route_raise_ParameterNameConflicts(app):
with pytest.raises(ParameterNameConflicts):
@app.get('/api/v1/<user>/<user>/')
def handler(request, user):
return text('OK')