Skip to content

[MEDIUM] catch (\Exception) misses \Throwable — silent audit loss under Doctrine proxy errors #557

@smarcet

Description

@smarcet

Summary

All 84 concrete audit log formatters in app/Audit/ConcreteFormatters/ use catch (\Exception $ex) to suppress errors. In PHP 8, TypeError and Error (e.g., thrown by Doctrine when accessing a lazy-loaded association on a detached entity) extend \Error, not \Exception. These will escape the catch block — causing the audit entry to be silently lost with no trace in the logs.

PR #499 surfaced this pattern through code review, but the issue is not new or isolated to that PR — it is a codebase-wide gap present in every formatter since the audit subsystem was introduced.

Scope

app/Audit/ConcreteFormatters/          # 84 files affected
├── PresentationFormatters/            # 10 formatters
├── ChildEntityFormatters/             # 2 formatters
└── *.php                              # 72 formatters

Run to confirm full scope:

grep -rl 'catch (\\Exception' app/Audit/ConcreteFormatters/ | wc -l
# => 84

Failure scenario

  1. An audit event fires for any entity.
  2. The formatter accesses a Doctrine lazy-loaded association (e.g., $subject->getSummit(), $subject->getLocation(), $subject->getConfig()) on a detached or expired entity.
  3. Doctrine throws a \Doctrine\ORM\EntityNotFoundException (caught — it extends \RuntimeException) or a TypeError / \Error (NOT caught — extends \Error, not \Exception).
  4. The exception propagates; AuditEventListener logs and swallows it — the audit log entry is permanently lost.

Fix

In every formatter's format() method, change:

} catch (\Exception $ex) {

to:

} catch (\Throwable $ex) {

This is a one-word change per file, consistent with PHP 8 best practice. Can be applied in bulk:

find app/Audit/ConcreteFormatters -name '*.php' -exec sed -i 's/catch (\\Exception \$ex)/catch (\\Throwable $ex)/g' {} +

Verify afterward that no formatter has any remaining catch (\Exception):

grep -r 'catch (\\Exception' app/Audit/ConcreteFormatters/

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions