简体   繁体   中英

Why isn't the code in the `else` section of my `try` block being run?

I'm using Python 2.7.3 with Flask 0.10.1 and SQL-Alchemy 0.9.1.

In my view code, I'm building an object for database input, and my code depends on the proper execution of two try / except / else blocks. It works as expected for the first block, both when exceptions occur and when they do not. When there's an exception, I get a collection of errors . When there's not an exception, the data get added to the database and the sample counter increments. Here's that snippet:

        try:
            new_sample = Sample()
            new_sample.build(sample)
        except SampleBuildingError as e:
            result_response['errors'].append('{0}: {1}'.format(sample['sample_name'], e.value) )
        else:
            db.session.add(new_sample)
            num_added += 1

Further down in the view function, I have a try / except / else / finally block. The data are being committed to the database, so the try portion is clearly working, as is the finally block. However, it appears that the else block is not being executed:

try:
    db.session.commit()
except Exception as e:
    result_response['error'] = "Failed on the database input: {0}".format( str(e) )
else:
    result_response['success'] = "The samples were input to the database successfully. {0} samples entered into the database, with {1} errors".format( num_added, len(errors) )
finally:
    return jsonify(result_response)

When there's an exception, I get json back with an error key and the database error, as expected. However, when the database commit is succesfully, I get a json object with every expected key except the success key.

It appears that the else block is being skipped, but I can't figure out why. I've tried putting the word bogus in the second line of the else block to try to force an error, but Python doesn't complain!

Here's the full view function:

@app.route("/kapasubmit", methods=['POST'])
def kapasubmit():
    num_added = 0
    result_response = {'errors': []}
    samples = request.json['data']
    for sample in samples:
        sample_check = Sample.query.filter_by( sample_name = sample['sample_name'] ).first()
        if sample_check is None:
            try:
                new_sample = Sample()
                new_sample.build(sample)
            except SampleBuildingError as e:
                result_response['errors'].append('{0}: {1}'.format(sample['sample_name'], e.value) )
            else:
                db.session.add(new_sample)
                num_added += 1
        else:
            result_response['errors'].append('{0}: This is a duplicate sample'.format(sample['sample_name']) )

    if num_added > 0:
        try:
            db.session.commit()
        except Exception as e:
            result_response['error'] = "Failed on the database input: {0}".format( str(e) )
        else:
            result_response['success'] = "The samples were input to the database successfully. {0} samples entered into the database, with {1} errors".format( num_added, len(errors) )
            bogus
        finally:
            return jsonify(result_response)
    else:
        result_response['error'] = "No valid samples submitted for input"
        return jsonify(result_response)

In case else block raises an exception, it gets ignored, since the interpreter has to execute return from the function. A demo:

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print "division by zero!"
...     else:
...         print "result is", result
...         print 1/0
...     finally:
...         return 1
... 
>>> divide(2,1)
result is 2
1

1/0 doesn't cause any traceback.

I think errors is not defined.

len(errors) would raise an exception, but not prevent the execution of the finally block, hence still returning some data, without having defined result_response['success']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM