Swiftgram / TDLibKit

Native Swift wrapper for Telegram's TDLib. Available on iOS, macOS, watchOS, tvOS and visionOS.
MIT License
105 stars 23 forks source link

SWIFT TASK CONTINUATION MISUSE: execute(query:) leaked its continuation! #3

Closed ggoraa closed 2 years ago

ggoraa commented 2 years ago

This is the message I get when I try to execute a normal function in TDLibKit, such as setAuthenticationPhoneNumber(phoneNumber:settings:). Invocation:

TextField("Phone number", text: $phoneNumber)
  .onSubmit {
      Task {
          try await tdApi.setAuthenticationPhoneNumber(phoneNumber: phoneNumber, settings: nil)
      }
  }

Where did I screw up?

Kylmakalle commented 2 years ago

Hey, I've been unable to run your app from https://github.com/ggoraa/moc due to missing files in git and reproduce the issue in unit tests even.

I think this is due to ARC weak self was used for async function execute(query:) which was removed https://github.com/Swiftgram/TDLibKit/commit/e39cf70f69c12362e860794ef94a10eafe15d6be#diff-0c4989f772de41032c2478b21eb80fc2c46d6f924f6920fda58ee15f574d92a9L13085

@ggoraa Can you please try with latest TDLibKit version 1.2.0?

ggoraa commented 2 years ago

Lemme try it, thanks!

ggoraa commented 2 years ago

And what do you mean "missing files"? Which exactly?

Kylmakalle commented 2 years ago

Clone the repo to clean directory and try to build it. Compiler will throw an error about missing source files.

ggoraa commented 2 years ago

think this is due to ARC weak self was used for async function execute(query:) which was removed

Well, possibly not this was the issue, because the app still fails to execute this statement with the error above

ggoraa commented 2 years ago

Clone the repo to clean directory and try to build it. Compiler will throw an error about missing source files.

Sorry, this is an issue in master branch. Can you try the viewmodels+di one?

Kylmakalle commented 2 years ago

I've debugged your app a bit and found out that client is not created on this stage of user flow. It's not nicely handled by framework so you're getting such errors.

The real error is that td client instance is not created. It may be caused by your DI library. image

P.S. Thank you for submitting this issue, I will fix error handling soon.

ggoraa commented 2 years ago

Oh, well that is awkward I have no idea why my DI library refuses to properly init TDLib 🤔 Anyways, thanks for your help! Gonna try fixing the issue

ggoraa commented 2 years ago

Did some more research on this problem. The thing is - the client is still destroyed, even when I use a totally new instance of TDLib (TdApi(client: TdClientImpl())) It is possible that the issue is not my DI library But the most confusing part is that this thing works fine in TdService, it easily gets the TdApi instance from Resolver and runs functions, such as setTdlibParameters But it is still broken in LoginView 🤔 well this is confusing

ggoraa commented 2 years ago

I found even more info When I place in .onAppear tdApi.client.run { _ in }, and then i run setAuthenticationPhoneNumber, the app just dies with the following error:

_Concurrency/CheckedContinuation.swift:164: Fatal error: SWIFT TASK CONTINUATION MISUSE: execute(query:) tried to resume its continuation more than once, returning Ok()! image If I remove the onAppear section, then it reverts to the old behavior I explained in the first message

ggoraa commented 2 years ago

Again, more info If I run the initialization right inside the LoginView, everything works like a charm. I even managed to log in to Telegram! This is definitely an issue with the DI library... this is embarassin'...

Kylmakalle commented 2 years ago

It is possible that the issue is not my DI library

It looks like your DI library somehow copies initial TdApi object and resets it's state.

ggoraa commented 2 years ago

Big thanks for help! And sorry for bothering you because of issues that i created on my end :(

Kylmakalle commented 2 years ago

_Concurrency/CheckedContinuation.swift:164: Fatal error: SWIFT TASK CONTINUATION MISUSE: execute(query:) tried to resume its continuation more than once, returning Ok()!

I've also encountered this bug. Fun fact, it was due to Error() can be successfully cast to Ok() type. It's now handled in latest TDLibKit 1.2.1 with some more error-handling logic that could help debugging later. https://github.com/Swiftgram/TDLibKit/commit/d8deb5e1cb0793401c065aad71ddba8e29fffb16