Turn getChild None and Deferred results into something Twisted Web can manage

This commit is contained in:
Jean-Paul Calderone 2020-10-15 16:14:06 -04:00
parent fa02e46033
commit 0339ba97b9
1 changed files with 22 additions and 7 deletions

View File

@ -20,6 +20,7 @@ from twisted.web.server import (
UnsupportedMethod, UnsupportedMethod,
) )
from twisted.web.util import ( from twisted.web.util import (
DeferredResource,
FailureElement, FailureElement,
redirectTo, redirectTo,
) )
@ -459,21 +460,35 @@ class TokenOnlyWebApi(resource.Resource, object):
raise WebError("'%s' invalid type for 't' arg" % (t,), http.BAD_REQUEST) raise WebError("'%s' invalid type for 't' arg" % (t,), http.BAD_REQUEST)
def exception_to_child(f): def exception_to_child(getChild):
""" """
Decorate ``getChild`` method with exception handling behavior to render an Decorate ``getChild`` method with exception handling behavior to render an
error page reflecting the exception. error page reflecting the exception.
""" """
@wraps(f) @wraps(getChild)
def g(self, name, req): def g(self, name, req):
try: bound_getChild = getChild.__get__(self, type(self))
return f(self, name, req) result = maybeDeferred(bound_getChild, name, req)
except Exception as e: result.addCallbacks(
description, status = humanize_exception(e) _getChild_done,
return resource.ErrorPage(status, "Error", description) _getChild_failed,
callbackArgs=(self,),
)
return DeferredResource(result)
return g return g
def _getChild_done(child, parent):
if child is None:
return resource.NoResource()
return child
def _getChild_failed(reason):
text, code = humanize_failure(reason)
return resource.ErrorPage(code, "Error", text)
def render_exception(render): def render_exception(render):
""" """
Decorate a ``render_*`` method with exception handling behavior to render Decorate a ``render_*`` method with exception handling behavior to render