Reputation: 3693
I noticed that app.handle_exception
doesn't seem to be called when the exception occurs with an app.test_request_context
:
from flask import *
app = Flask(__name__)
app.handle_exception = lambda e: 'exception!'
@app.route('/foo')
def foo():
x = 1 / 0
return 'ok'
if __name__ == '__main__':
#app.run(port=81) # handle_exception works here
with app.test_request_context('/foo'):
print app.dispatch_request() # but not here
Is this the expected behavior?
Upvotes: 1
Views: 2068
Reputation: 43071
Not sure if this is what you're after: according to the docs for dispatch_request:
Does the request dispatching. Matches the URL and returns the return value of the view or error handler. This does not have to be a response object. In order to convert the return value to a proper response object, call make_response().
Changed in version 0.7: This no longer does the exception handling, this code was moved to the new full_dispatch_request().
So, perhaps replace...
with app.test_request_context('/foo'):
print app.dispatch_request() # but not here
...with...
with app.test_request_context('/foo'):
print app.full_dispatch_request() # Hopefully this works now :)
Upvotes: 1
Reputation: 2631
You can easily override this behaviour and force handling exceptions with same handler.
def run_test(path=None,check_func=None,*args,**kwargs):
with app.test_request_context(path,*args,**kwargs):
try:
data=app.dispatch_request()
if check_func is not None:
check_func()
else:
print data
except Exception as e:
print app.handle_exception(e)
run_test('/')
run_test('/other')
def current_test(data):
assert 'has some content' in data
run_test('/should_be_checked',check_func=current_test)
And another word.
Your approach does not work because you just do not use that part of Flask, which actually catches Exception. You are calling context directly.
Quote from documentation:
If you look into how the Flask WSGI application internally works, you will find a piece of code that looks very much like this:
def wsgi_app(self, environ):
with self.request_context(environ):
try:
response = self.full_dispatch_request()
except Exception, e:
response = self.make_response(self.handle_exception(e))
return response(environ, start_response)
But! Following would be the correct way to do it, since all Flask methods on every level will be called in appropriate way:
with app.test_request_context():
with app.test_client() as client:
resp = client.get('/')
#and if you need content of response: print resp.data
Upvotes: 1