Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NSInvalidArgumentException - Uncaught Exception: unrecognized selector sent to instance 0x28313f580 #426

Open
frno opened this issue Jun 3, 2022 · 6 comments
Labels
bug Something isn't working. It's clear that this does need to be fixed.

Comments

@frno
Copy link

frno commented Jun 3, 2022

Hello. I have a flutter application which uses 7 different Ably streams. When the application is resumed from idle then sometimes the following crash occurs. I have not been able to successfully replicate this when I wish to replicate it, but it occurs daily when I am using my app. I have been able to catch the following using Sentry. The 7 Ably streams share the same Ably client so the client is only created once. I recently changed the application from connecting the 7 Ably streams sequentially to connecting them by running multiple futures in parallel. I also recently changed the application from using basic authentication to using token authentication where Ably Token is issued by our servers and passed to clients as described in 2.2 of here. Before these changes were made, I had not experienced this error.

Below is the factory method for how client options is created.

  factory AblyClient.fromServerToken(AblyTokenSupplier tokenSupplier){
    // Create
    final clientOptions = ClientOptions()
      ..authCallback = (TokenParams tokenParams) async {
        try {
          AblyTokenInfo tokenInfo = await tokenSupplier.getAblyTokenInfo();
          return TokenDetails(tokenInfo.token, expires: tokenInfo.expiresRaw, issued: tokenInfo.issuedRaw, capability: tokenInfo.capability, clientId: tokenInfo.clientId);
        } on ClientException catch (e) {
          print('Failed to createTokenRequest: $e');
          rethrow;
        }
      };
    return AblyClient._(clientOptions);
  }

ably_flutter version: 1.2.14

Running on iPhone 11 Pro, running software version 15.5 (19F77)

Exception Type: EXC_CRASH (SIGABRT)
Crashed Thread: 19

Application Specific Information:
-[FlutterError userInfo]: unrecognized selector sent to instance 0x28313f580

Thread 19 Crashed:
0   CoreFoundation                  0x34d0c9288         __exceptionPreprocess
1   libobjc.A.dylib                 0x37eb40740         objc_exception_throw
2   CoreFoundation                  0x34d1a6fc0         -[NSObject(NSObject) doesNotRecognizeSelector:]
3   CoreFoundation                  0x34d05de94         ___forwarding___
4   CoreFoundation                  0x34d05cf6c         __forwarding_prep_0___
5   Ably                            0x101b82a18         +[ARTErrorInfo createFromNSError:]
6   Ably                            0x101b44384         __81+[ARTPaginatedResult executePaginated:withRequest:andResponseProcessor:callback:]_block_invoke
7   Ably                            0x101b6ff94         __80-[ARTRestInternal executeRequestWithAuthentication:withMethod:force:completion:]_block_invoke
8   Ably                            0x101b26564         __47-[ARTAuthInternal _authorize:options:callback:]_block_invoke_3
9   Ably                            0x101b26204         __47-[ARTAuthInternal _authorize:options:callback:]_block_invoke
10  Ably                            0x101b246a8         __54-[ARTAuthInternal _requestToken:withOptions:callback:]_block_invoke.283
11  Ably                            0x101b86eec         -[ARTCancellableFromCallback invokeWithResult:error:]
12  Ably                            0x101b86e00         __47-[ARTCancellableFromCallback initWithCallback:]_block_invoke
13  Ably                            0x101b24a7c         __54-[ARTAuthInternal _requestToken:withOptions:callback:]_block_invoke_3

Flutter version: 3.0.1
Dart version: 2.17.1

Link to full issue: https://sentry.io/share/issue/0eb7c0ef9ebc4b4bb30c77fb9cc6e40d/

I am wondering what the Ably code is doing here and what I can do on my side to prevent this fatal crash. Thank you.

┆Issue is synchronized with this Jira Bug by Unito

@frno
Copy link
Author

frno commented Jul 11, 2022

I am still experiencing this issue, is there anything I can provide Ably with?

@ikbalkaya
Copy link
Contributor

Thanks for submitting this issue @frno. We will investigate this.

@ikbalkaya
Copy link
Contributor

@frno Can you clarify what you mean by 'Ably stream'? Do you mean an Ably channel? Also it would be really helpful if you could provide a sample code block of how you parallelized those streams (or channels)

@frno
Copy link
Author

frno commented Aug 23, 2022

Hello Thank you for talking a look at this. Yes I mean channels.

First ablyClient is created using a tokenSupplier. Tokensupplier is implemented as a call to our REST API which issues an Ably Token (using server to server).

ablyClient = AblyClient.fromServerToken(_tokenSupplier);

factory AblyClient.fromServerToken(AblyTokenSupplier tokenSupplier){
    // Create
    final clientOptions = ClientOptions()
      ..authCallback = (TokenParams tokenParams) async {
        try {
          AblyTokenInfo tokenInfo = await tokenSupplier.getAblyTokenInfo();
          return TokenDetails(tokenInfo.token, expires: tokenInfo.expiresRaw, issued: tokenInfo.issuedRaw, capability: tokenInfo.capability, clientId: tokenInfo.clientId);
        } on Exception catch (e) {
          print('Failed to createTokenRequest: $e');
          rethrow;
        }
      };

    Realtime realtime = Realtime(options: clientOptions);
    return AblyClient._(realtime);
  }

Then this ablyClient is used in seven different instances which all connect to seperate channels.

await Future.wait([
	instanceWhichDealsWithChannel1.Connect(ablyClient),
	instanceWhichDealsWithChannel2.Connect(ablyClient),
	instanceWhichDealsWithChannel3.Connect(ablyClient),
	instanceWhichDealsWithChannel4.Connect(ablyClient),
	instanceWhichDealsWithChannel5.Connect(ablyClient),
	instanceWhichDealsWithChannel6.Connect(ablyClient),
	instanceWhichDealsWithChannel7.Connect(ablyClient),
      ]);

On connect the following is done:

        RealtimeChannel channel = realtime.channels.get('channelStr');
	var messageStream = channel.subscribe();
`StreamSubscription<Message>` is setup using `messageStream.listen`

then history is called:
	var params = RealtimeHistoryParams(direction: 'backwards', limit: 50);
      	var result = await channel.history(params);
which retrieves message until a certain threshold is met.

I have found that this bug has to do with the authCallback on ClientOptions and when errors are rethrown. I have found that if I removed the rethrow and swallowed the error and instead returned an invalid token string that the fatal exception no longer occured.

I switched the 'rethrow' with return TokenDetails("abcd1234"); and have not observed this exception anymore.

@davyskiba
Copy link
Contributor

Hello @frno,
Sorry for the delay. This issue seems to be related to handling auth exceptions in native code.
I'm raising this issue with the Objective C team.

@davyskiba
Copy link
Contributor

@frno, we're having a problem with reproducing this issue, could you prepare a minimal project on which you are able to reproduce this issue?

@sync-by-unito sync-by-unito bot added the bug Something isn't working. It's clear that this does need to be fixed. label Feb 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working. It's clear that this does need to be fixed.
Development

No branches or pull requests

3 participants