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

Unhandled Runtime Error Error: ERR_ALREADY_CALLED #19

Open
kcbuilder opened this issue Oct 17, 2024 · 10 comments
Open

Unhandled Runtime Error Error: ERR_ALREADY_CALLED #19

kcbuilder opened this issue Oct 17, 2024 · 10 comments

Comments

@kcbuilder
Copy link

Failed to launch application using latest version of template

Steps to Reproduce

  • created telegram bot
  • created application using template, https://github.com/kcbuilder/tg-app-example - public version is here
  • started local version with pnpm run dev
  • started local tunnel with ngrok ngrok http 3000
  • set menu link for created bot in BotFather

When trying to open bot in telegram getting problem
image

Tested for application created with same template a few month ago, all working good
image

@heyqbnk
Copy link
Member

heyqbnk commented Oct 22, 2024

I wasn't able to reproduce the problem using the nextjs-template, nor the repository you provided. It just opens as usual for me :(

Check if you are using the latest pnpm version, try removing node_modules and installing again

UPD: Ok, I have it now. We can see the issue when using the latest version of sdk-react. Looking into it

@braveltd
Copy link

braveltd commented Oct 22, 2024

Fixed by changing core/init.ts to

import {
  backButton,
  viewport,
  themeParams,
  miniApp,
  initData,
  $debug,
  init as initSDK,
} from "@telegram-apps/sdk-react";

/**
 * Initializes the application and configures its dependencies.
 */
export function init(debug: boolean): void {
  // Set @telegram-apps/sdk-react debug mode.
  $debug.set(debug);

  // Initialize special event handlers for Telegram Desktop, Android, iOS, etc.
  // Also, configure the package.
  initSDK();

  // Mount all components used in the project.
  if (backButton.isSupported()) {
    backButton.mount();
  }

  // Define components-related CSS variables.
  if (!miniApp.isMounted()) {
    miniApp.mount();
    miniApp.bindCssVars();
  }
  if (!themeParams.isMounted()) {
    themeParams.mount();
    themeParams.bindCssVars();
  }

  initData.restore();

  if (!viewport.isMounted() && !viewport.isMounting()) {
    void viewport.mount().catch((e) => {
      console.error("Something went wrong mounting the viewport", e);
    });
  }

  if (viewport.isMounted()) {
    viewport.bindCssVars();
  }
}

In my project's i don't use eruda, but you can include eruda, i don't think it will break anythink!

@kcbuilder
Copy link
Author

Fixed by changing core/init.ts to

import {
  backButton,
  viewport,
  themeParams,
  miniApp,
  initData,
  $debug,
  init as initSDK,
} from "@telegram-apps/sdk-react";

/**
 * Initializes the application and configures its dependencies.
 */
export function init(debug: boolean): void {
  // Set @telegram-apps/sdk-react debug mode.
  $debug.set(debug);

  // Initialize special event handlers for Telegram Desktop, Android, iOS, etc.
  // Also, configure the package.
  initSDK();

  // Mount all components used in the project.
  if (backButton.isSupported()) {
    backButton.mount();
  }

  // Define components-related CSS variables.
  if (!miniApp.isMounted()) {
    miniApp.mount();
    miniApp.bindCssVars();
  }
  if (!themeParams.isMounted()) {
    themeParams.mount();
    themeParams.bindCssVars();
  }

  initData.restore();

  if (!viewport.isMounted() && !viewport.isMounting()) {
    void viewport.mount().catch((e) => {
      console.error("Something went wrong mounting the viewport", e);
    });
  }

  if (viewport.isMounted()) {
    viewport.bindCssVars();
  }
}

In my project's i don't use eruda, but you can include eruda, i don't think it will break anythink!

Got problem with applying theme for dark mode with this approach, not sure about correlation here but would like to share this case
image

@braveltd
Copy link

Fixed by changing core/init.ts to

import {
  backButton,
  viewport,
  themeParams,
  miniApp,
  initData,
  $debug,
  init as initSDK,
} from "@telegram-apps/sdk-react";

/**
 * Initializes the application and configures its dependencies.
 */
export function init(debug: boolean): void {
  // Set @telegram-apps/sdk-react debug mode.
  $debug.set(debug);

  // Initialize special event handlers for Telegram Desktop, Android, iOS, etc.
  // Also, configure the package.
  initSDK();

  // Mount all components used in the project.
  if (backButton.isSupported()) {
    backButton.mount();
  }

  // Define components-related CSS variables.
  if (!miniApp.isMounted()) {
    miniApp.mount();
    miniApp.bindCssVars();
  }
  if (!themeParams.isMounted()) {
    themeParams.mount();
    themeParams.bindCssVars();
  }

  initData.restore();

  if (!viewport.isMounted() && !viewport.isMounting()) {
    void viewport.mount().catch((e) => {
      console.error("Something went wrong mounting the viewport", e);
    });
  }

  if (viewport.isMounted()) {
    viewport.bindCssVars();
  }
}

In my project's i don't use eruda, but you can include eruda, i don't think it will break anythink!

Got problem with applying theme for dark mode with this approach, not sure about correlation here but would like to share this case image

probably i should move all bindCss after mount's. checking if mounted. like with viewport!

@braveltd
Copy link

In my current project, i have only dark mode possible, so i don't know if it's my init.ts code that breaks or somethink else. for me, what i provided works with [email protected].

@heyqbnk
Copy link
Member

heyqbnk commented Oct 23, 2024

The problem is probably related to the React's StrictMode performing all effects twice. It is probably resetting refs also, we use them in the useTelegramMock (useClientOnce actually) function mocking the environment.

To solve it, we need to call the init function only once before the React tree is rendered, or at least unmount all mounted SDK components.

I currently have no time for it and can fix the problem only on the next week. Feel free to propose a solution

@vladutjs
Copy link

Has anybody got around this issue?

@miguelaeh
Copy link

I can confirm that this is the fix: #19 (comment)

@vikiival
Copy link

vikiival commented Nov 4, 2024

Based on I managed to get it working #19 (comment)

The diff is that I placed themeParams.bindCssVars(); outside of the if statement 🤷

additionally I have added
import '@telegram-apps/telegram-ui/dist/styles.css'; in Root.tsx

TL;DR

export function init(debug: boolean): void {
  // Set @telegram-apps/sdk-react debug mode.
  $debug.set(debug);

  // Initialize special event handlers for Telegram Desktop, Android, iOS, etc.
  // Also, configure the package.
  initSDK();

  // Mount all components used in the project.
  if (backButton.isSupported()) {
    backButton.mount();
  }

  // Define components-related CSS variables.
  if (!miniApp.isMounted()) {
    miniApp.mount();
    miniApp.bindCssVars();
  }
  if (!themeParams.isMounted()) {
    themeParams.mount();
  }
  
  themeParams.bindCssVars();

  initData.restore();

  if (!viewport.isMounted() && !viewport.isMounting()) {
    void viewport.mount().catch((e) => {
      console.error("Something went wrong mounting the viewport", e);
    });
  }

  if (viewport.isMounted()) {
    viewport.bindCssVars();
  }
}

@braveltd
Copy link

Based on I managed to get it working #19 (comment)

The diff is that I placed themeParams.bindCssVars(); outside of the if statement 🤷

additionally I have added import '@telegram-apps/telegram-ui/dist/styles.css'; in Root.tsx

TL;DR

export function init(debug: boolean): void {
  // Set @telegram-apps/sdk-react debug mode.
  $debug.set(debug);

  // Initialize special event handlers for Telegram Desktop, Android, iOS, etc.
  // Also, configure the package.
  initSDK();

  // Mount all components used in the project.
  if (backButton.isSupported()) {
    backButton.mount();
  }

  // Define components-related CSS variables.
  if (!miniApp.isMounted()) {
    miniApp.mount();
    miniApp.bindCssVars();
  }
  if (!themeParams.isMounted()) {
    themeParams.mount();
  }
  
  themeParams.bindCssVars();

  initData.restore();

  if (!viewport.isMounted() && !viewport.isMounting()) {
    void viewport.mount().catch((e) => {
      console.error("Something went wrong mounting the viewport", e);
    });
  }

  if (viewport.isMounted()) {
    viewport.bindCssVars();
  }
}

i believe you can make PR with that code. at least this works for me. importing styles helped a lot. or we should just wait for react-ui, react-sdk to get fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants