| name | audit-exception-safety |
| description | Audit exception safety and failure atomicity across all throw sites |
| context | fork |
| agent | auditor |
| disable-model-invocation | true |
Audit the cache for exception safety defects. For every code path where
exceptions can be thrown, determine whether the cache is left consistent.
Assume at least one exception safety bug exists. If your analysis yields
zero findings, re-examine catch-commit-rethrow paths — explain specifically
why no exception scenario leaves inconsistent state.
Priority #1: catch-commit-rethrow in doComputeIfAbsent and remap. This is
the most commonly misunderstood pattern and historically the most fragile.
Trace the EXACT sequence of committed mutations, notification delivery, and
exception propagation for every exception type.
User-provided code that can throw:
- CacheLoader.load / loadAll / reload
- Weigher.weigh
- Expiry.expireAfterCreate / expireAfterUpdate / expireAfterRead
- Mapping functions passed to compute, computeIfAbsent, merge
- RemovalListener.onRemoval / EvictionListener
Runtime exceptions:
6. OutOfMemoryError during node/reference allocation
7. StackOverflowError from deep re-entrancy
8. RejectedExecutionException from executor
For each throw site:
-
List every mutation already committed before the throw point.
-
Determine whether the catch block rolls back or commits.
-
Check for:
- Phantom entries: Node in CHM but invisible to eviction/expiration
- Orphaned references: WeakReference created but node rolled back
- Counter drift: weightedSize out of sync with actual entries
- Lost notifications: notifyEviction without notifyRemoval, or vice versa
- Leaked futures: CompletableFuture never completed
- Stuck refresh: refresh flag set but never cleared
-
For catch-commit-rethrow (doComputeIfAbsent, remap), verify:
- Catches Throwable, not just RuntimeException
- Committed state is fully consistent
- Original exception is preserved
-
For OutOfMemoryError specifically:
- Can AddTask/UpdateTask OOME orphan a CHM entry?
- Can WeakKeyReference/WeakValueReference OOME leave half-constructed node?
For each defect: state the throw site, mutations committed, inconsistent
state, and a concrete triggering scenario.