Reputation: 1558
I have a very very simple flask server just for learning purposes but what I don't understand is when i return abort(404)
it triggers the exception block and doesn't actually return the 404 it actually returns:
HI 2017-02-16 18:46:27,048 - __main__ - ERROR - Exception on /dddd [GET]
Traceback (most recent call last):
File "/usr/local/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.5/site-packages/flask/app.py", line 1478, in full_dispatch_request
response = self.make_response(rv)
File "/usr/local/lib/python3.5/site-packages/flask/app.py", line 1566, in make_response
raise ValueError('View function did not return a response')
ValueError: View function did not return a response
Flask server code:
from flask import Flask, request, redirect, jsonify, abort, Response
@application.route("/<short_link>", methods=['GET'])
def get_short_link(short_link):
try:
if id_exists(short_link):
return redirect(find_full_link_by_id(short_link), code=302)
return abort(404)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
print("SOME PLACEHOLDER")
if __name__ == '__main__':
application.run()
where id_exists
queries a MySql database, this all works I have tested this in segregation.
My understanding would be that having this:
if id_exists(short_link):
return redirect(find_full_link_by_id(short_link), code=302)
return abort(404)
it should always return.
Also my server has a post endpoint which returns a 415 if you don't use application/json
as the content type. This works as expected:
try:
if request.headers['Content-Type'] == 'application/json':
full_link = request.get_json(force=True).get('fullLink')
return jsonify(shortLink=generate(full_link, 5), fullLink=full_link)
return abort(Response('Unsupported Media Type', 415))
except:
# Some error handling omitted for this purpose
which does correctly return the 415 response. I have tried returning 200, 415, 403 etc just to see if its something special about the 404 but no look.
What am I doing wrong? I'm new to this framework.
EDIT: Just to clarify if I use a debugging tool and update my code to be:
try:
if id_exists(short_link):
return redirect(find_full_link_by_id(short_link), code=302)
return abort(404)
except Exception as e:
#do something... removed for the sake of clarity
the debugging says the exception (e
) is actually 404: Not Found
using PyCharm IDE
Upvotes: 2
Views: 6708
Reputation: 5449
abort()
is a non returning function. It doesn't return because the only thing it does is raise an exception. So the first mistake you are makeing is return abort(...)
. The return
is never reached.
The second mistake is the try except
statement.
This is a good example why a bare except
is bad. Don't do that unless you know for sure that you need it.
You explicitly raise an exception and catch that in the except
block. Why raise in the first place if you catch it directly?
To solve your problem use this pattern:
if object_not_found:
abort(404)
do_something
return your_response
Note: it's just abort
without return
.
Always make sure your view does return a response.
Your code didn't work because you caught the abort exception in your except
block and you didn't return a response after that.
Upvotes: 6