Skip to content

Commit

Permalink
Fire the pipelines error caught method when NWConnection's state chan…
Browse files Browse the repository at this point in the history
…ges 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
  • Loading branch information
Cartisim authored Oct 25, 2023
1 parent 0561bee commit 16ca413
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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>?) {
Expand Down
53 changes: 53 additions & 0 deletions Tests/NIOTransportServicesTests/NIOTSConnectionChannelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 16ca413

Please sign in to comment.