diff --git a/Sources/NIOCore/AsyncChannel/AsyncChannelOutboundWriterHandler.swift b/Sources/NIOCore/AsyncChannel/AsyncChannelOutboundWriterHandler.swift index daa35fd63e..8fa2111274 100644 --- a/Sources/NIOCore/AsyncChannel/AsyncChannelOutboundWriterHandler.swift +++ b/Sources/NIOCore/AsyncChannel/AsyncChannelOutboundWriterHandler.swift @@ -137,7 +137,7 @@ internal final class NIOAsyncChannelOutboundWriterHandler @inlinable func handlerRemoved(context: ChannelHandlerContext) { self.context = nil - self.sink?.finish() + self.sink?.finish(error: ChannelError.ioOnClosedChannel) self.writer = nil } @@ -150,7 +150,7 @@ internal final class NIOAsyncChannelOutboundWriterHandler @inlinable func channelInactive(context: ChannelHandlerContext) { - self.sink?.finish() + self.sink?.finish(error: ChannelError.ioOnClosedChannel) context.fireChannelInactive() } diff --git a/Tests/NIOCoreTests/AsyncChannel/AsyncChannelTests.swift b/Tests/NIOCoreTests/AsyncChannel/AsyncChannelTests.swift index cafddee308..cbaec06640 100644 --- a/Tests/NIOCoreTests/AsyncChannel/AsyncChannelTests.swift +++ b/Tests/NIOCoreTests/AsyncChannel/AsyncChannelTests.swift @@ -81,6 +81,24 @@ final class AsyncChannelTests: XCTestCase { } } + func testAsyncChannelThrowsWhenChannelClosed() async throws { + let channel = NIOAsyncTestingChannel() + let wrapped = try await channel.testingEventLoop.executeInContext { + return try NIOAsyncChannel(wrappingChannelSynchronously: channel) + } + + try await channel.close(mode: .all) + + do { + try await wrapped.executeThenClose { _, outbound in + try await outbound.write("Test") + } + XCTFail("Expected an error to be thrown") + } catch { + XCTAssertEqual(error as? ChannelError, ChannelError.ioOnClosedChannel) + } + } + func testFinishingTheWriterClosesTheWriteSideOfTheChannel() async throws { let channel = NIOAsyncTestingChannel() let closeRecorder = CloseRecorder()