corydolphin / flask-cors

Cross Origin Resource Sharing ( CORS ) support for Flask
https://flask-cors.corydolphin.com/
MIT License
877 stars 137 forks source link

cross_origin decorator doesn't work when view raises exception #241

Open ajenkins-cargometrics opened 5 years ago

ajenkins-cargometrics commented 5 years ago

If I configure CORS using flask_cors.CORS(app), then CORS headers are added to responses even when a view function raises an exception. However if I use the cross_origin decorator instead to configure CORS, it only works if the view function exits normally. I could understand this being the case for arbitrary exceptions, but this is true even for HTTPExceptions, which are often used to signal non-success error codes. For instance:

from flask import Flask, abort
from flask_cors import CORS, cross_origin

app = Flask(__name__)
CORS(app, resources={'/foo': {'origins': '*'}})

# responses from this route will have CORS headers added
@app.route('/foo')
def foo():
  abort(401, 'Not authorized')

# responses from this route will not have CORS headers added
@app.route('/bar')
@cross_origin()
def bar():
    abort(401, 'Not authorized')

I would have expected both of the routes defined above to behave the same, but in fact only the /foo route gets CORS headers added, because flask.abort raises an HTTPException.

It's easy to see why this is so from looking at the code for the cross_origin decorator, and it looks easy to fix. Just wondering if this difference in behavior was intentional for some reason I'm not thinking of. If not, I'd be happy to submit a pull request fixing this.

corydolphin commented 5 years ago

Hi @ajenkins-cargometrics the behavior is not intentional, a pull request would be much appreciated. It is a little tricky since flask has different handling when running in debug v.s. production.

Let me know how you go! Really appreciate any contributions!