Release paths silently swallow unexpected exceptions via catch (...) plus ASSERT(0)
Summary¶
Several live release paths still use catch (...) { ASSERT(0); } or an
equivalent shape that turns unexpected exceptions into effectively silent
failure in non-debug builds.
This is broader than the focused ArchiveRecovery item in BUG-002: the same
pattern appears in multiple subsystems that process external input, files, or
network-derived state.
Representative Live Sites¶
srchybrid/ArchiveRecovery.cppsrchybrid/Collection.cppsrchybrid/WebServer.cppsrchybrid/ServerSocket.cpp
These are representative anchors, not an exhaustive list.
Why This Matters¶
In debug builds, ASSERT(0) makes the failure visible. In release builds, the
assert disappears and the catch (...) often leaves only a quiet early-return
or partial fallback path.
That makes production diagnosis harder:
- users get no actionable error signal
- logs miss the root event
- corrupted or partial state can be misinterpreted as a normal functional miss
Intended Fix Direction¶
Do not treat this as a blanket “log everything and continue” sweep.
Preferred remediation pattern:
- preserve the current safe-fail behavior where it is already bounded
- add explicit logging where practical and meaningful
- convert a few sites to typed exception handling where the thrown failure shape is already known
- avoid rethrow/crash behavior unless the local code path is truly unsafe to continue
Current Mainline Outcome¶
The first bounded diagnostics slice landed on main in commit 9992cb1
(BUG-034 BUG-035: add bounded runtime failure logs), and monitored shared
refresh failure handling was narrowed in commit 60b3b44.
The collection-import slice adds typed logging for unreadable binary collection entries and keeps unexpected import failures explicit while preserving the existing tolerant skip behavior for malformed per-file entries.
The collection-file import slice extends that work inside each serialized file entry: hostile tag counts are rejected before parsing, malformed individual tags are logged instead of swallowed silently, and hashless entries are rejected with a typed reason so the outer collection loader can skip them explicitly.
The secure-ident slice narrows ClientCredits crypto/signature failures by
making buffer and key-length rejection explicit and keeping unexpected
signature exceptions on the existing zero-length failure result.
The server TCP packet slice makes the existing recover-or-disconnect policy for
server packet processing explicit through ServerSocketSeams: search-result
and found-source parse failures remain recoverable, compressed-packet unpack
failures remain consumed input, and unexpected packet-processing exceptions now
use safe fallback metadata for failure logs.
The legacy WebServer search slice keeps unexpected search-start exceptions on
the existing generic error response through WebServerLegacySeams, and makes
the historical gzip failure fallback to an uncompressed response explicit.
The 2026-05-01 release-readiness scan found no rollback-level regression in the
recent hardening slices, but it did identify srchybrid/ClientUDPSocket.cpp as
the next best high-signal target: unknown release exceptions while processing
external UDP packets are still converted to "Unknown exception" and logged
only when verbose logging is enabled.
The client UDP slice landed on main in commit 6b76687 and adds a
ClientUDPSocketSeams policy so unexpected packet-processing exceptions force
a release log while ordinary malformed packet diagnostics remain verbose-gated.
Native coverage for that policy landed in emulebb-build-tests commit
6af34cc; the supported Debug x64 test lane passed after the change.
The server UDP slice landed on main in commit 16f50ba and applies the same
policy to CUDPSocket::ProcessPacketError: expected server UDP packet parse
failures remain verbose-gated, while unexpected release exceptions force a
diagnostic log. Native coverage landed in emulebb-build-tests commit
80bfa14; the supported Debug x64 test lane passed after the change.
The async socket helper-init slice landed on main in commit cf4bbb1 and
makes CAsyncSocketEx::InitAsyncSocketExInstance() helper-window allocation or
construction exceptions release-visible through an explicit DebugLogError
while preserving the existing cleanup and false return. Native policy
coverage landed in emulebb-build-tests commit ad49ff8; the supported Debug
x64 build-app and test lanes passed after the change.
The Windows toast notification slice landed on main in commit c6e3d9c and
keeps toast initialization/display failure behavior fail-soft while making
typed C++/WinRT hresult_error failures and unexpected exceptions visible in
the debug/error log. This covers both CreateToastNotifier initialization and
per-toast Show failures, including payload cleanup after failed display.
Validation passed with workspace validate, Debug x64 main app build, and
Release x64 main app build.
This item is therefore In Progress, not Open. It is not Done: the
2026-05-01 scan still finds broad release-silent exception handling in current
main, including 123 catch (...) matches across app source. Future slices
should stay targeted and high-signal rather than attempting a mechanical
codebase-wide rewrite.
Relationship to Existing Items¶
BUG-002remains the focusedArchiveRecoveryrepresentative itemBUG-013remains the separateArchiveRecoveryOOM/null-deref item
This item exists to track the broader release-silent exception-swallowing pattern across subsystems, not to replace those narrower archive items.