Closed omgore closed 7 months ago
Thanks for the detailed report. Can you elaborate on this part:
EXPECTED BEHAVIOUR: The delegate method transportDidClose() should send the error wrapped using SignalRError.webError(statusCode: statusCode) instead of error from Error object.
I am curious why your expectation is that the error should be wrapped as SignalRError.webError
?
Thank you for quick response.
We have used skipNegotiation
flag for websocket connection, it is calling urlSession(didcompleteWithError)
. Whenever there is error from server, we are not getting error code in delegate method connectionDidFailToOpen
.
We can see error code 401 is coming, but we are not getting it outside. But if we wrap this in SignalRError.webError
then we are able to get this in delegate method connectionDidFailToOpen
.
Let us know if there is any other way to get error code in delegate method.
When the transport closes due to an error, it forwards the original error: https://github.com/moozzyk/SignalR-Client-Swift/blob/a028e01acc5ef32c0f4933c4f56d645d64b36500/Sources/SignalRClient/WebsocketsTransport.swift#L115
You should be able to use it to retrieve the statusCode if you need it, similarly to how the code logging the error does it. The interface does not promise that the error you'll get will be a SignalRError. In fact, it is impossible to implement this for WebSockets due to the protocol specification. When a webSocket connection is being initialized, it uses the HTTP protocol, and if an error occurs at this stage, you can get an HTTP status code. However, once the HTTP request is upgraded to WebSockets (statusCode 101), the errors will be WebSockets codes as described in: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code. The code does nothing special to distinguish between these two cases and returns the original error.
In practical terms, I am not sure why knowing the code is useful - the issue is on the server side, and the client cannot do much to fix it.
We cast the error as NSError and then using that -1011 code. But not getting 401 code that is coming.
I see. -1011 is NSURLErrorBadServerResponse
which is documented here (along with other related errors): https://developer.apple.com/documentation/foundation/1508628-url_loading_system_error_codes/nsurlerrorbadserverresponse
This is the error the URLSession
returns.
I am still curious how would you use the statusCode if you had it.
Actually when we received status code as 401- Unauthorized, which means web socket connection with server has failed to open because user is not authenticated. It can be because of session token expiry.
So once we receive 401 status code, we just re authenticate the user and send new session token to server.
I see. A possible workaround could be to always refresh the token before starting the connection.
I merged a change today, which will return SignalRError.webError
if the statusCode is available: 3d46db30157c3b0ef0ca57f25acc7726938e6450
PROBLEM: Actual error code returned by server is not passed on to the delegate
transportDidClose()
method withskipNegotiation
flag. We've used the SignalR-Client-Swift in our project and we have enabled theskipNegotiation
flag. Whenever server sends the any error code (E.g. 401 error code) we are not receiving that through delegate method. It only gives the error fromError
object. Due to that we are unable to take action based on error code.EXPECTED BEHAVIOUR: The delegate method
transportDidClose()
should send the error wrapped usingSignalRError.webError(statusCode: statusCode)
instead of error from Error object.LOGS:
EXPECTED CODE CHANGE: Line 115:
delegate?.transportDidClose(SignalRError.webError(statusCode: statusCode))
Let me know If is there any alternate way to handle this when
skipNegotiation
flag is enabled.