我有个有趣的问题。基本上我有一个Flask restful API应用程序,其中我有一个HTML页面,登录用户可以在该页面上创建API用户。这是由SQLAlchemy模型类Apiusers处理的,我在其中使用validates decorator来确保用户名和电子邮件地址遵守规则。所有的工作都很好,当用户输入无效信息时,它会抛出一个异常,但无论如何我都无法在烧瓶中捕捉到它。我想捕捉它并向用户闪回一条关于它的消息,但它却抛出了一个内置的.AssertionError当不在调试模式下时,它会给出500个内部服务器错误页。在
尝试使用不同类型的异常-ValueError,定义自定义异常类,最后用except:捕获所有错误,但异常最终总是无法处理。我也遇到了类似的问题:https://github.com/marshmallow-code/webargs/issues/122其中提到flask restful劫持了所有HTTP异常的处理,但这是从2016年开始的。在任何一种情况下,我都能够在使用validates之前在同一个位置捕捉到SQLAlchemy惟一约束异常,所以我不认为这是个问题。在models.py:
from sqlalchemy.orm import validates
class Apiusers(db.Model):
__tablename__ = 'apiusers'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True)
password_hash = db.Column(db.String(128))
def __repr__(self):
return self.username
@validates('username')
def validate_username(self, key, username):
if not username:
raise AssertError('No username provided')
if Apiusers.query.filter(Apiusers.username == username).first():
raise AssertError('Username is already in use')
if len(username) < 5 or len(username) > 20:
raise AssertError('Username must be between 5 and 20 characters')
return username
@validates('email')
def validate_email(self, key, email):
if not email:
raise AssertError('No email provided')
if not re.match("[^@]+@[^@]+\.[^@]+", email):
raise AssertError('Provided email is not an email address')
return email
views.py:
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
_user = request.form['username']
_email = request.form['emails']
record = Apiusers(username=_user, email=_email)
try:
db.session.add(record)
db.session.commit()
except AssertError as e:
flash('{}'.format(str(e)), 'danger')
return render_template("register.html")
return render_template("regresult.html")
以下是尝试添加空用户名时的stacktrace:
^{pr2}$