Merge pull request #29 from huge-success/master
merge upstream master branch
This commit is contained in:
commit
9ae6dfb6d2
|
@ -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")
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -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',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user