@@ -219,20 +219,35 @@ - (void)onWrittenData:(TcpSocketClient *)client msgId:(NSNumber *)msgId {
219219
220220- (void )onConnect : (TcpSocketClient *)client {
221221 GCDAsyncSocket *socket = [client getSocket ];
222- [self sendEventWithName: @" connect"
223- body: @{
224- @" id" : client.id ,
225- @" connection" : @{
226- @" localAddress" : [socket localHost ],
227- @" localPort" :
228- [NSNumber numberWithInt: [socket localPort ]],
229- @" remoteAddress" : [socket connectedHost ],
230- @" remotePort" : [NSNumber
231- numberWithInt: [socket connectedPort ]],
232- @" remoteFamily" : [socket isIPv4 ] ? @" IPv4"
233- : @" IPv6"
234- }
235- }];
222+ NSString *localAddress = [socket localHost ];
223+ NSString *remoteAddress = [socket connectedHost ];
224+ // The socket can disconnect between this callback being queued and run,
225+ // in which case the address getters return nil. Building the connection
226+ // dictionary with a nil value throws NSInvalidArgumentException and
227+ // crashes the app, so emit an error instead of the connect event -
228+ // skipping silently would hang the JS side waiting for a callback.
229+ if (localAddress != nil && remoteAddress != nil ) {
230+ [self sendEventWithName: @" connect"
231+ body: @{
232+ @" id" : client.id ,
233+ @" connection" : @{
234+ @" localAddress" : localAddress,
235+ @" localPort" :
236+ [NSNumber numberWithInt: [socket localPort ]],
237+ @" remoteAddress" : remoteAddress,
238+ @" remotePort" : [NSNumber
239+ numberWithInt: [socket connectedPort ]],
240+ @" remoteFamily" : [socket isIPv4 ] ? @" IPv4"
241+ : @" IPv6"
242+ }
243+ }];
244+ } else {
245+ [self sendEventWithName: @" error"
246+ body: @{
247+ @" id" : client.id ,
248+ @" error" : @" Socket disconnected before connect could be reported"
249+ }];
250+ }
236251}
237252
238253- (void )onListen : (TcpSocketClient *)server {
0 commit comments