Fire the pipelines error caught method when NWConnection's state changes to failed (#187)

* Fire the pipelines  error caughted method when NWConnection's state changes to failed

* Added check if failed error is ChannelError.eof and added a unit test for forwarding failed connnection state errors

* Completing a promise for the error caught

* Fixed Typo

* Removed whitespace

* Binding the listener to port 0 and connecting to listerner's localAddress
This commit is contained in:
Cartisim Development 2023-10-25 12:22:53 +04:00 committed by GitHub
parent 0561bee80c
commit 16ca413e3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 0 deletions

View File

@ -272,6 +272,12 @@ extension StateManagedNWConnectionChannel {
self.connectPromise = nil
pendingConnect.fail(error)
}
// Step 4 Forward the connection state failed Error
let channelError = error as? ChannelError
if channelError != .eof {
self.pipeline.fireErrorCaught(error)
}
}
public func doHalfClose0(error: Error, promise: EventLoopPromise<Void>?) {

View File

@ -865,5 +865,58 @@ class NIOTSConnectionChannelTests: XCTestCase {
.wait()
XCTAssertNoThrow(try connection.close().wait())
}
func testErrorIsForwardedFromFailedConnectionState() throws {
final class ForwardErrorHandler: ChannelDuplexHandler {
typealias OutboundIn = ByteBuffer
typealias InboundIn = ByteBuffer
private let testCompletePromise: EventLoopPromise<Error>
let listenerChannel: Channel
init(testCompletePromise: EventLoopPromise<Error>, listenerChannel: Channel) {
self.testCompletePromise = testCompletePromise
self.listenerChannel = listenerChannel
}
func channelActive(context: ChannelHandlerContext) {
listenerChannel
.close()
.whenSuccess { _ in
_ = context.channel.write(ByteBuffer(data: Data()))
}
}
func errorCaught(context: ChannelHandlerContext, error: Error) {
let error = error as? ChannelError
XCTAssertNotEqual(error, ChannelError.eof)
XCTAssertEqual(error, ChannelError.ioOnClosedChannel)
XCTAssertNotNil(error)
testCompletePromise.succeed(error!)
}
}
let listener = try NIOTSListenerBootstrap(group: self.group)
.childChannelInitializer { channel in
return channel.eventLoop.makeSucceededVoidFuture()
}
.bind(host: "localhost", port: 0)
.wait()
let testCompletePromise = self.group.next().makePromise(of: Error.self)
let connection = try NIOTSConnectionBootstrap(group: self.group)
.channelInitializer { channel in
channel.pipeline.addHandler(
ForwardErrorHandler(
testCompletePromise: testCompletePromise,
listenerChannel: listener
)
)
}
.connect(to: listener.localAddress!)
.wait()
XCTAssertNoThrow(try connection.close().wait())
XCTAssertNoThrow(try testCompletePromise.futureResult.wait())
}
}
#endif