为什么不运行我的`try`块的`else`部分中的代码?

时间:2014-02-27 21:21:05

标签: python json exception-handling flask

我正在使用带有Flask 0.10.1和SQL-Alchemy 0.9.1的Python 2.7.3。

在我的视图代码中,我正在为数据库输入构建一个对象,我的代码依赖于两个try / except / else块的正确执行。对于第一个块,它可以正常工作,无论是异常发生还是不发生异常。当出现异常时,我会得到errors的集合。如果没有异常,则数据会添加到数据库中,并且样本计数器会递增。这是片段:

        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

在视图功能中,我有一个try / except / else / finally块。数据被提交到数据库,因此try部分显然正常工作,finally块也是如此。但是,似乎没有执行else块:

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)

当出现异常时,我会按照预期的那样使用error键和数据库错误返回json。但是,当数据库提交成功时,我得到一个json对象,其中包含每个预期的键,除了 success键。

似乎正在跳过else块,但我无法弄清楚原因。我已经尝试将单词bogus放在else块的第二行以试图强制错误,但Python不会抱怨!

以下是完整视图功能:

@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)

2 个答案:

答案 0 :(得分:3)

如果else块引发异常,它将被忽略,因为解释器必须从函数执行return。演示:

>>> 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不会导致任何追溯。

答案 1 :(得分:2)

我认为errors未定义。

len(errors)会引发异常,但不会阻止finally块的执行,因此仍会返回一些数据,而没有定义result_response['success']