failed to connect to server is wrongly treated as handshake error
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"ERROR: handshake failed ... %@", [error localizedDescription]);
_isConnected = NO;
_isConnecting = NO;
if ([_delegate respondsToSelector:@selector(socketIO:onError:)]) {
NSMutableDictionary *errorInfo = [NSDictionary dictionaryWithObject:error forKey:NSLocalizedDescriptionKey];
NSError *err = [NSError errorWithDomain:SocketIOError
code:SocketIOHandshakeFailed
userInfo:errorInfo];
[_delegate socketIO:self onError:err];
}
// TODO: deprecated - to be removed
else if ([_delegate respondsToSelector:@selector(socketIOHandshakeFailed:)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[_delegate socketIOHandshakeFailed:self];
#pragma clang diagnostic pop
}
}
Even if the server was not reachable, it is being handled as handshake error, i suggest fixing it by adding a new error type, namely SocketIOServerCouldNotBeReached
//socketio.h
typedef enum {
SocketIOServerRespondedWithInvalidConnectionData = -1,
SocketIOServerRespondedWithDisconnect = -2,
SocketIOHeartbeatTimeout = -3,
SocketIOWebSocketClosed = -4,
SocketIOTransportsNotSupported = -5,
SocketIOHandshakeFailed = -6,
SocketIODataCouldNotBeSend = -7,
SocketIOServerCouldNotBeReached = -8,
} SocketIOErrorCodes;
and perhaps something along this line
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"ERROR: handshake failed ... %@, %d", [error localizedDescription], [error code]);
_isConnected = NO;
_isConnecting = NO;
if ([_delegate respondsToSelector:@selector(socketIO:onError:)]) {
NSMutableDictionary *errorInfo = [NSDictionary dictionaryWithObject:error forKey:NSLocalizedDescriptionKey];
NSError *err = nil;
if ( 403 == error.code ) { // forbidden, according to the code in socket.io https://github.com/LearnBoost/socket.io/blob/0.9.14/lib/manager.js#L812
err = [NSError errorWithDomain:SocketIOError
code:SocketIOHandshakeFailed
userInfo:errorInfo];
} else if ( -1002 == error.code ) { // failed to reach server
err = [NSError errorWithDomain:SocketIOError
code:SocketIOServerCouldNotBeReached
userInfo:errorInfo];
}
[_delegate socketIO:self onError:err];
}
// TODO: deprecated - to be removed
else if ([_delegate respondsToSelector:@selector(socketIOHandshakeFailed:)] && 403 == error.code) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[_delegate socketIOHandshakeFailed:self];
#pragma clang diagnostic pop
}
}
but of course written properly with maybe a mapping of error with the error code or something
seems like under the connection errors, apple has a lot of different error codes...
kCFURLErrorUnknown = -998,
kCFURLErrorCancelled = -999,
kCFURLErrorBadURL = -1000,
kCFURLErrorTimedOut = -1001,
kCFURLErrorUnsupportedURL = -1002,
kCFURLErrorCannotFindHost = -1003,
kCFURLErrorCannotConnectToHost = -1004,
kCFURLErrorNetworkConnectionLost = -1005,
kCFURLErrorDNSLookupFailed = -1006,
kCFURLErrorHTTPTooManyRedirects = -1007,
kCFURLErrorResourceUnavailable = -1008,
kCFURLErrorNotConnectedToInternet = -1009,
kCFURLErrorRedirectToNonExistentLocation = -1010,
kCFURLErrorBadServerResponse = -1011,
kCFURLErrorUserCancelledAuthentication = -1012,
kCFURLErrorUserAuthenticationRequired = -1013,
kCFURLErrorZeroByteResource = -1014,
kCFURLErrorCannotDecodeRawData = -1015,
kCFURLErrorCannotDecodeContentData = -1016,
kCFURLErrorCannotParseResponse = -1017,
kCFURLErrorInternationalRoamingOff = -1018,
kCFURLErrorCallIsActive = -1019,
kCFURLErrorDataNotAllowed = -1020,
kCFURLErrorRequestBodyStreamExhausted = -1021,
kCFURLErrorFileDoesNotExist = -1100,
kCFURLErrorFileIsDirectory = -1101,
kCFURLErrorNoPermissionsToReadFile = -1102,
kCFURLErrorDataLengthExceedsMaximum = -1103,
the easiest thing would be to add the error.code to the errorInfo then you can handle the "handshake error" differently depending on the errorcode in your application.
well i suppose that can be done too, but that wouldnt be a very accurate representation of the true error wouldnt it? And this is a very general error, that is triggered by NSURLConnection. Of course, arguable since the only thing NSURLConnection is doing currently is for handshake?
I actually forked and implemented something similar to what I suggested and it seems to work, so what is your call for this? Since i think this really does cause certain problems in the long run, like for my case, if handshake failed I unauthenticate the app and if it cannot be reached it will just run offline mode
Edit: I meant if this is not fixed it can e a problem for some people in the long run