# ERROR: tearDown (tests.test_db.TestDB.test_insert)
Traceback (most recent call last):
  File "test_db.py", line 42, in tearDown
    self.conn.close()
AttributeError: 'NoneType' object has no attribute 'close'

- **ID:** `python/unittest-teardown-exception-masks-failure`
- **Domain:** python
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

setUp failed or was skipped, leaving self.conn unset, but tearDown still runs and raises. The teardown error masks the original setup failure.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 3.9 | active | — | — |
| 3.12 | active | — | — |

## Workarounds

1. **** (92% success)
   ```
   Guard teardown with hasattr/getattr:

def tearDown(self):
    conn = getattr(self, 'conn', None)
    if conn is not None:
        conn.close()
   ```
2. **** (95% success)
   ```
   Use addCleanup in setUp so cleanup only runs for successfully created resources:

def setUp(self):
    self.conn = create_conn()
    self.addCleanup(self.conn.close)
   ```

## Dead Ends

- **** — Silences real teardown errors and leaks resources, hiding the root cause of future failures. (85% fail)
- **** — Leaves DB connections and temp files open across tests, causing flaky failures later. (80% fail)
