TypeError swallowed in decorated handlers
See original GitHub issueIf a TypeError
is raised within a handler, which has been decorated by a “wrapper” function whose first argument is not called self
, the TypeError
is swallowed and a 404 HTTP Error is returned instead.
from functools import wraps
import cherrypy
def dec(f):
@wraps(f)
def wrapper(handler, *args, **kwargs):
return f(handler, *args, **kwargs)
return wrapper
class HelloWorld(object):
@dec
def index(self, *args, **kwargs):
raise TypeError('OOPS')
return "Hello world!"
index.exposed = True
if __name__ == '__main__':
cherrypy.quickstart(HelloWorld())
Response is a 404:
> curl -sD - 'http://localhost:8080/' -o /dev/null
HTTP/1.1 404 Not Found
Server: CherryPy/8.1.2
Content-Length: 1267
Content-Type: text/html;charset=utf-8
Date: Fri, 16 Dec 2016 16:05:18 GMT
Without the decorator @dec
, one correctly gets a 500.
The problem is here: https://github.com/cherrypy/cherrypy/blob/master/cherrypy/_cpdispatch.py#L105
When inspecting the “callable”, CherryPy checks for the name of the first argument and strips it out if it’s called self
. It then goes on inspecting the other arguments and raises a 404 if some arguments are missing or unknown.
But if the “callable”'s first argument is not called “self”, as in the decorated handler above (where it’s called “handler”), then CherryPy mistakenly returns a “404 argument ‘handler’ is unknown”.
Issue Analytics
- State:
- Created 7 years ago
- Comments:7 (7 by maintainers)
Top GitHub Comments
One option, that would only work on Python3, though, is to check if the “callable” has a
__wrapped__
attribute when checking if it’s been wrapped or not and callgetargspec
on__wrapped__
if so:>>> getargspec(callable.__wrapped__)
(['self'], 'args', 'kwargs', None)
See https://docs.python.org/3/library/functools.html#functools.update_wrapper
For Python2, at leasts the docs should suggest to set the
__wrapped__
attribute manually to the original wrapper.PR available here: https://github.com/cherrypy/cherrypy/pull/1531