bottlepy / bottle

bottle.py is a fast and simple micro-framework for python web-applications.
http://bottlepy.org/
MIT License
8.37k stars 1.46k forks source link

Errors in mounted apps does not go to the root app #1202

Closed martinlehoux closed 4 years ago

martinlehoux commented 4 years ago
# views/user.py
@user_app.error(404)
def error404(err):
    print(err)

This handles this error :

curl http://localhost:8000/users/mee
(404, "Not found: '/mee'")% 

But if error is handled at app level, it doesn't work

# app.py
application.mount('/users', user_app)
@application.error(404)
def error404(err):
    return(str(err))
curl http://localhost:8000/users/mee

    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html>
        <head>
            <title>Error: 404 Not Found</title>
            <style type="text/css">
              html {background-color: #eee; font-family: sans-serif;}
              body {background-color: #fff; border: 1px solid #ddd;
                    padding: 15px; margin: 15px;}
              pre {background-color: #eee; border: 1px solid #ddd; padding: 5px;}
            </style>
        </head>
        <body>
            <h1>Error: 404 Not Found</h1>
            <p>Sorry, the requested URL <tt>&#039;http://localhost:8000/users/mee&#039;</tt>
               caused an error:</p>
            <pre>Not found: &#039;/mee&#039;</pre>
        </body>
    </html>

Is this the desired behavior ? i.e. Errors occuring in a mounted app should only be handled in this mounted app

defnull commented 4 years ago

Yes, this is intended. Mounted applications stay independent from the parent. For example, plugins installed to the parent are also not applied to routes of the mounted child application. The same is (should be*) true for error handlers or other configuration.

In Bottle 0.12, mount() actually calls the child application as if it were a wsgi callable. If you want errors to fall through, you can try disabling app.catchall in the child application. I'm not entirely sure if that works, though. Would have to test it.

In Bottle 0.13+ mount() works differently for instances of bottle.Bottle. Error handling is mixed up currently, if I see that right in the code. That needs to be fixed. Mounted applications should stay as independent as possible.

If you really want to share error handlers in both applications, than you can do that of cause: child.error_handler = parent.error_handler