Creating failing webuser from flask still adds the user

Using the web_user module, the email address has a SQL constraint to be unique. When adding a new web user from the desktop client with an email address already in the database it will fail and no new user is created. This is the right behavior.

Now I want to do the same from my webapp. The app sends an email address and password in JSON format to the backend which is Flask with the flask-tryton package. The backend then calls the create function on web.user to create the user. When using an email address which is already in the database I get an error back which is expected.

What is not expected, is that even an error is returned, the user is still created in the database.

My code:

app.config['TRYTON_USER'] = 2 # normal user

WebUser = tryton.pool.get('web.user')

@app.route('/register_email', methods=['POST'])
@tryton.transaction()
def register_email():
    data = request.get_json()
    res = {}
    if 'username' and 'password' in data:
        try:
            user = WebUser.create([{
                'email': data['username'],
                'password': data['password']
            }])
            res['result'] = []
        except Exception as e:
            # return error. This can be about unique email addresses
            res['error'] = {'error': "{0}".format(str(e))}
    else:
        res['error'] = {'error': 'Wrong data entered.'}

    return json.dumps(res)

So I get the error “E-mail of active web user must be unique.” back, but the user is still created in the database.

Python 3.9.6, flask-tryton 0.11.0 and trytond 6.4.0 with a sqlite database (will that be a problem?)

Do I need some extra checks to overcome this problem?

If you do not raise an exception, transaction decorator does not know that it has to rollback the transaction.
The best is to use the abort function from Flask.

Indeed, adding abort fixes this.

try:
    # ......
except Exception as e:
    # return error. This can be about unique email addresses
    res['error'] = {'error': "{0}".format(str(e))}
    abort(400, json.dumps(res))

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.