errors aren't being handled on branched resources
Branched routes don't handle errors of the "base" Resource. Hopefully an example to start things off will be beneficial.
from klein import Klein
from werkzeug.exceptions import NotFound
app1 = Klein()
app2 = Klein()
#----- Catch Errors -----#
@app1.route('/<path:allpaths>')
def catchall(request, allpaths):
request.setResponseCode(404)
return 'Catch-All: paths'
@app1.handle_errors(ValueError)
def handle(request, failure):
request.setResponseCode(400)
return 'Catch: ValueError()'
@app1.handle_errors(NotFound)
def huh(request, failure):
request.setResponseCode(413)
return 'Catch-All: NotFound()'
#----- Routes -----#
@app1.route('/one')
def one(request):
raise ValueError('raised a ValueError')
@app1.route('/two', branch=True)
def two(request):
return app2.resource()
@app2.route('/blue')
def blue(request):
raise ValueError('blue') # this won't be handled by app1
if __name__ == '__main__':
app1.run('localhost', 9000)
If a route isn't present, then either the catchall() or huh() function will execute. Similarly, if a ValueError is raised, then the handle() function is executed.
> curl localhost:9000/
# Catch-All: NotFound()
> curl localhost:9000/foo/baz/bar
# Catch-All: paths
> curl localhost:9000/one
# Catch: ValueError()
However, if an invalid route from a branched resource is used, then the errors are left unhandled. The following will result in a traceback and the default Twisted 404 page:
> curl localhost:9000/two/blue
> curl localhost:9000/two/red
This all makes it very tedious and very error prone when creating expansive web or RESTful applications because devs must then ensure each each Resource has all the appropriate error handling. Though there are ways around this, there should be a dedicated "Klein" way to map branched routes to the base set of routes.
This is closely related to #205.