Skip to content

fix: event handler exception safety + non-happy-path tests#75

Merged
Kiryuumaru merged 1 commit into
masterfrom
fix/unhappy-path-tests-and-event-safety
May 7, 2026
Merged

fix: event handler exception safety + non-happy-path tests#75
Kiryuumaru merged 1 commit into
masterfrom
fix/unhappy-path-tests-and-event-safety

Conversation

@Kiryuumaru
Copy link
Copy Markdown
Owner

Summary

Fixes event handler exception safety and adds comprehensive non-happy-path test coverage.

Bug Fixes

Event handler exceptions crash the mux (fixed)

All event invocations (ChannelOpened, ChannelClosed, ChannelAccepted, Connected, Ready, Disconnected, Error, Reconnecting) are now wrapped in RaiseEvent helper methods with try-catch. A throwing user event handler can no longer crash the multiplexer, channels, or dispose.

Duplicate channel ID silently broken (fixed)

ChannelRegistry.RegisterPendingAcceptChannel used indexer assignment which silently overwrites. Changed to TryRegisterPendingAcceptChannel with TryAdd — second OpenChannel("same") now correctly throws MultiplexerException(ErrorCode.ChannelExists).

New Tests (92)

UnhappyPathTests.cs (53 tests)

  • Multiplexer state violations (before start, after dispose)
  • Channel operations after close (write, read, double close)
  • Cancellation token propagation
  • Connection failure scenarios
  • GoAway protocol edge cases
  • Channel state transitions
  • AsStream error paths
  • Transit error paths (MessageTransit, StreamTransit, DuplexStreamTransit)
  • Event firing on error paths
  • Lookup methods with invalid input
  • Multiple dispose safety
  • Empty and boundary writes
  • Stats consistency after errors
  • Configuration edge cases

ApiMisuseTests.cs (39 tests)

  • Event handler resilience (ChannelOpened, ChannelClosed, Disconnected, Error)
  • DuplexStreamTransit misuse (read/write after dispose, null args, CanRead/CanWrite, Seek, multiple dispose)
  • DeltaTransit misuse (send/receive after dispose, wrong direction, POCO without TypeInfo, empty batch)
  • Concurrent misuse (multiple threads disposing, same-ID race, concurrent write+close, concurrent GoAway)
  • GoAway + channel interactions
  • Write before ready
  • AcceptChannel/OpenChannel misuse (same ID, empty string, very long IDs)
  • StreamTransit sync path errors
  • Stats verification
  • Lookup methods with invalid input
  • AsStream after channel close

Test Results

393 total tests, 392 pass consistently (1 pre-existing flaky stress test: ExtremeStressTests.Scale_ConcurrentBidirectional_StressTest).

Bug fixes:
- Wrap all event invocations in try-catch via RaiseEvent helpers
  (throwing user handlers no longer crash mux/channels/dispose)
- Reject duplicate channel IDs in ChannelRegistry
  (TryRegisterPendingAcceptChannel uses TryAdd instead of indexer)

New tests (92 total):
- UnhappyPathTests.cs (53): multiplexer state violations, channel
  ops after close, cancellation, GoAway, transit errors, lookups
- ApiMisuseTests.cs (39): event handler resilience, DuplexStream/
  DeltaTransit misuse, concurrent misuse, GoAway+channel, write
  before ready, AcceptChannel/OpenChannel misuse, stats
@Kiryuumaru Kiryuumaru enabled auto-merge (squash) May 7, 2026 05:37
@Kiryuumaru Kiryuumaru disabled auto-merge May 7, 2026 05:54
@Kiryuumaru Kiryuumaru merged commit 4298a59 into master May 7, 2026
22 checks passed
@Kiryuumaru Kiryuumaru deleted the fix/unhappy-path-tests-and-event-safety branch May 7, 2026 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant