Swallowed Exception in StackExchange.Redis

StackExchange/StackExchange.RedisPR#2995 ↗
GCI0007BLOCKError HandlingConcurrency

Context

StackExchange.Redis PR#2995 refactored ChannelMessageQueue.cs. It added a bare catch { } block that silently swallows all exceptions in the message dispatch loop. When an exception occurs in the queue processing, the failure is invisible - no log, no rethrow, no signal to callers. The connection appears healthy while messages are silently dropped.

Diff evidence

src/StackExchange.Redis/ChannelMessageQueue.cs
// Before
public async Task WriteAsync(ChannelMessage message)
{
await _channel.Writer.WriteAsync(message);
}
// After - bare catch added in the dispatch loop
private async Task ProcessAsync()
{
try
{
while (await _channel.Reader.WaitToReadAsync())
{
var message = _channel.Reader.TryRead(out var msg) ? msg : default;
await _handler(message);
}
}
+ catch { } // <-- GCI0007: swallowed exception
}
[GCI0007] Error Handling Integrity (4 occurrences)
Location : src/StackExchange.Redis/ChannelMessageQueue.cs (lines 140, 148, 272, 284)
Summary  : Swallowed exception detected
Evidence : catch { } // matches MessageCompletable
Why      : Empty or silent catch blocks hide failures, making bugs invisible and
           debugging nearly impossible.
Action   : Log the exception, rethrow it, or handle it explicitly.

Why it matters

StackExchange.Redis is downloaded over 400 million times. A catch { } block in the message dispatch loop means any exception thrown by a subscriber handler - including OutOfMemoryException, OperationCanceledException on shutdown, or transient network faults - disappears without a trace. The queue continues processing, the channel appears healthy, and messages are silently dropped. The only indication of a problem is that subscribers stop receiving messages, with no exception in logs, no error return, and no way to distinguish the failure from a quiet period with no traffic.

Detection rule

This finding is produced by GCI0007 - Error Handling Integrity. The rule flags empty catch blocks, catch blocks that only rethrow, and cases where exception handlers are removed relative to the previous version of the code.