question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TypeError swallowed in decorated handlers

See original GitHub issue

If 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:closed
  • Created 7 years ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
lbollacommented, Dec 16, 2016

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 call getargspec 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.

0reactions
lbollacommented, Dec 16, 2016
Read more comments on GitHub >

github_iconTop Results From Across the Web

Strangeness with a decorator - python - Stack Overflow
Your decorator needs to return a function, but it's not returning anything, hence the 'TypeError: 'NoneType' object is not callable'.
Read more >
[Solved]-Strange Docker + Celery Bug-docker - appsloveworld
The only unnamed argument it accepted is the function to be decorated. Otherwise it would raise a TypeError and be swallowed by supervisord...
Read more >
History — CherryPy 10.0.1.dev10+ng1a62192.d20170207 ...
#1530: Fix the issue with TypeError being swallowed by decorated handlers. ... 1460: Fix KeyError in Bus.publish when signal handlers: set in config....
Read more >
Professional Error Handling With Python - Code
The simplest way to do it is to let all exceptions propagate (unless they can be handled confidently and swallowed earlier) and then...
Read more >
History — CherryPy 18.6.1.dev49+g98929b51.d20210117 ...
PR #1806: Support handling multiple exceptions when processing hooks as ... #1530: Fix the issue with TypeError being swallowed by decorated handlers.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found