diff --git a/web/webapi.py b/web/webapi.py index 0981181..1ee1e9d 100644 --- a/web/webapi.py +++ b/web/webapi.py -46,7 +46,20 @@ class HTTPError(Exception): header(k, v) self.data = data Exception.__init__(self, status) - + +def HTTPErrorSwitch(dft_class): + """Returns a function that returns an app-specific handler for the given + exception, or an instance of `dft_class` by default + """ + handler_name = dft_class.__name__.lower() + def switch(*args, **kwargs): + for app in ctx.get('app_stack', [])[::-1]: + app_handler = app.get(handler_name) + if callable(app_handler): + return app_handler(*args, **kwargs) + return dft_class() + return switch + def _status_code(status, data=None, classname=None, docstring=None): if data is None: data = status.split(" ", 1)[1] -119,41 +132,27 @@ class TempRedirect(Redirect): tempredirect = TempRedirect -class BadRequest(HTTPError): - """`400 Bad Request` error.""" - message = "bad request" - def __init__(self): - status = "400 Bad Request" - headers = {'Content-Type': 'text/html'} - HTTPError.__init__(self, status, headers, self.message) +BadRequest = _status_code("400 Bad Request") +badrequest = HTTPErrorSwitch(BadRequest) -badrequest = BadRequest +NotFound = _status_code("404 Not Found") +notfound = HTTPErrorSwitch(NotFound) -class _NotFound(HTTPError): - """`404 Not Found` error.""" - message = "not found" - def __init__(self, message=None): - status = '404 Not Found' - headers = {'Content-Type': 'text/html'} - HTTPError.__init__(self, status, headers, message or self.message) +Unauthorized = _status_code("401 Unauthorized") +unauthorized = HTTPErrorSwitch(Unauthorized) -def NotFound(message=None): - """Returns HTTPError with '404 Not Found' error from the active application. - """ - if message: - return _NotFound(message) - elif ctx.get('app_stack'): - return ctx.app_stack[-1].notfound() - else: - return _NotFound() +Forbidden = _status_code("403 Forbidden") +forbidden = HTTPErrorSwitch(Forbidden) + +NotAcceptable = _status_code("406 Not Acceptable") +notacceptable = HTTPErrorSwitch(NotAcceptable) + +Conflict = _status_code("409 Conflict") +conflict = HTTPErrorSwitch(Conflict) -notfound = NotFound +PreconditionFailed = _status_code("412 Precondition Failed") +preconditionfailed = HTTPErrorSwitch(PreconditionFailed) -unauthorized = Unauthorized = _status_code("401 Unauthorized") -forbidden = Forbidden = _status_code("403 Forbidden") -notacceptable = NotAcceptable = _status_code("406 Not Acceptable") -conflict = Conflict = _status_code("409 Conflict") -preconditionfailed = PreconditionFailed = _status_code("412 Precondition Failed") class NoMethod(HTTPError): """A `405 Method Not Allowed` error.""" -170,7 +169,7 @@ class NoMethod(HTTPError): data = None HTTPError.__init__(self, status, headers, data) -nomethod = NoMethod +nomethod = HTTPErrorSwitch(NoMethod) class Gone(HTTPError): """`410 Gone` error.""" -180,7 +179,7 @@ class Gone(HTTPError): headers = {'Content-Type': 'text/html'} HTTPError.__init__(self, status, headers, self.message) -gone = Gone +gone = HTTPErrorSwitch(Gone) class _InternalError(HTTPError): """500 Internal Server Error`.""" -201,7 +200,7 @@ def InternalError(message=None): else: return _InternalError() -internalerror = InternalError +internalerror = HTTPErrorSwitch(InternalError) def header(hdr, value, unique=False): """