]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commit
Fix variable scope issue in try-except
authorAccela Zhao <accelazh@gmail.com>
Thu, 4 Feb 2016 02:11:09 +0000 (18:11 -0800)
committerAccela Zhao <accelazh@gmail.com>
Thu, 4 Feb 2016 08:53:27 +0000 (00:53 -0800)
commit20d920b07625ec5780b3785035a0280c3b317ba4
tree99734e3938556ad3d98180f97dbad7e96b24bea6
parent9299e7aebea42095fe1fa09b89d7297b5a53826e
Fix variable scope issue in try-except

Below piece of code in cinder.backup.api.API.create does not handle
the scope of variable 'backup' properly. In general variable used in
except clause has larger scope than what is in try clause.

```
    try:
        ...
        backup = objects.Backup(context=context, **kwargs)
        backup.create()
        ...
    except Exception:
            ...
            backup.destroy()
            ...
```

The first problem: if object.Backup.__init__ raises exception,
variable 'backup' won't be assigned. However the cleanup code invokes
backup.destroy(), which results in an UnboundLocalError. The original
exception of __init__ is dropped, instead UnboundLocalError is raised
up-level. I know that for now objects.Backup.__init__ doesn't have
chance to raise exception, but when writing code we should not rely
on such assumption.

The second problem: backup.create() invokes DB. If an DB exception is
raised, backup.id won't be assigned. Any access to backup.id will
result in an "NotImplementedError: Cannot load 'id' in the base
class". However, when cleaning up, the backup.destroy() does access
backup.id. So we have the similar problem as the first one, and the
original exception is overrode by NotImplementedError.

This patch fixes it by adding a first-assignment outside try clause,
and add a safe check in except clause. The added test cases, if run
on the original code, it will show how the above problem occurs.

Closes-Bug: #1541745
Change-Id: I0e55c342ac489ff1ef27c0597b6dcba588778a04
cinder/backup/api.py
cinder/tests/unit/test_backup.py