Skip to content

spp_attachment_av_scan: 7 remaining except Exception sites can swallow database errors (follow-up to #384) #385

Description

@gonzalesedwin1123

Context

PR #384 fixed the two except Exception blocks on the create/write request path in
spp_attachment_av_scan/models/ir_attachment.py: they swallowed database errors, which
left execution continuing on an aborted transaction, so the next SQL statement failed in
unrelated code (InFailedSqlTransaction) and the real cause was invisible. It also
defeated odoo.service.model.retrying, which would have transparently retried the
serialization failure that triggered the incident.

The same file has seven more bare except Exception blocks with the same latent
hazard, deliberately left out of #384 because their blast radius differs: they run inside
queue jobs or explicit button actions, where a poisoned transaction is confined to that
job/request rather than corrupting an unrelated user request mid-flight.

Sites (line numbers at ba1f3ef)

Line Method Path
251 _scan_for_malware queue job
342 _quarantine (inner, encryption fallback) queue job
371 _quarantine (outer) queue job
443 _notify_security_admins queue job
530 action_restore_quarantined button
607 action_download_quarantined_for_analysis button
680 action_rescan button

Why it still matters

  • A swallowed DB error in a queue job makes the job report success on a dead
    transaction
    — the scan result/quarantine write is silently lost, and the job is not
    retried even though the failure was transient and retryable.
  • In the button actions, a swallowed DB error turns into a misleading follow-on error
    (or a silent no-op behind a success toast).
  • The job-worker incident chain (odoo-job-worker#22, spp_base_common: menu-icon env.ref hook can take down a job worker on a poisoned cursor #383) showed how far a poisoned
    cursor can propagate once code continues past a DB error.

Proposed direction

Reuse the _MUST_NOT_SWALLOW = (psycopg2.Error, ConcurrencyError) guard from #384:
add an except _MUST_NOT_SWALLOW: raise clause ahead of each broad catch. Per-site
review needed — e.g. _quarantine's encryption fallback (line 342) intentionally falls
back to plain storage on encryption errors and must keep doing so for non-DB errors.

Tests should mirror #384's two-sided pattern: a DB error propagates; a non-DB error is
still swallowed/logged and the best-effort behavior (fallback, notification skip) is
preserved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions