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

4.0.1 Error thrown in built Electron app #365

Closed
4 tasks done
Araxeus opened this issue Mar 22, 2023 · 13 comments · Fixed by #367
Closed
4 tasks done

4.0.1 Error thrown in built Electron app #365

Araxeus opened this issue Mar 22, 2023 · 13 comments · Fixed by #367
Labels
bug Something isn't working

Comments

@Araxeus
Copy link
Contributor

Araxeus commented Mar 22, 2023

Steps to reproduce

Build an Electron app using require('youtubei.js');

It will work in dev mode, but once the app is built then it will fail to load

Failure Logs

TypeError: Cannot read properties of undefined (reading 'url')
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\node_modules\youtubei.js\bundle\node.cjs:16362:33)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1196:10)
    at Module.load (node:internal/modules/cjs/loader:1011:32)
    at Module._load (node:internal/modules/cjs/loader:846:12)
    at f._load (node:electron/js2c/asar_bundle:2:13330)
    at Module.require (node:internal/modules/cjs/loader:1035:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\plugins\downloader\back.js:23:46)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
TypeError: Cannot read properties of undefined (reading 'url')
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\node_modules\youtubei.js\src\platform\node.ts:104:33)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1196:10)
    at Module.load (node:internal/modules/cjs/loader:1011:32)
    at Module._load (node:internal/modules/cjs/loader:846:12)
    at Function.f._load (node:electron/js2c/asar_bundle:2:13330)
    at Module.require (node:internal/modules/cjs/loader:1035:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\plugins\downloader\back.js:23:46)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
TypeError: Cannot read properties of undefined (reading 'url')
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\node_modules\youtubei.js\src\platform\node.ts:104:33)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1196:10)
    at Module.load (node:internal/modules/cjs/loader:1011:32)
    at Module._load (node:internal/modules/cjs/loader:846:12)
    at Function.f._load (node:electron/js2c/asar_bundle:2:13330)
    at Module.require (node:internal/modules/cjs/loader:1035:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\plugins\crossfade\back.js:2:23)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
TypeError: Cannot read properties of undefined (reading 'url')
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\node_modules\youtubei.js\src\platform\node.ts:104:33)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1196:10)
    at Module.load (node:internal/modules/cjs/loader:1011:32)
    at Module._load (node:internal/modules/cjs/loader:846:12)
    at Function.f._load (node:electron/js2c/asar_bundle:2:13330)
    at Module.require (node:internal/modules/cjs/loader:1035:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\plugins\downloader\back.js:23:46)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
Error occurred in handler for 'audio-url': No handler registered for 'audio-url'
TypeError: Cannot read properties of undefined (reading 'url')
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\node_modules\youtube    at Module._compile (node:internal/modules/cjs/loader:1141:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1196:10)
    at Module.load (node:internal/modules/cjs/loader:1011:32)
    at Module._load (node:internal/modules/cjs/loader:846:12)
    at Function.f._load (node:electron/js2c/asar_bundle:2:13330)
    at Module.require (node:internal/modules/cjs/loader:1035:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\plugins\downloader\back.js:23:46)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
(node:6124) UnhandledPromiseRejectionWarning: TypeError: Cannot read properties of undefined (reading 'url')
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\node_modules\youtubei.js\src\platform\node.ts:104:33)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1196:10)
    at Module.load (node:internal/modules/cjs/loader:1011:32)
    at Module._load (node:internal/modules/cjs/loader:846:12)
    at Function.f._load (node:electron/js2c/asar_bundle:2:13330)
    at Module.require (node:internal/modules/cjs/loader:1035:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (C:\Users\Araxeus\AppData\Local\Programs\youtube-music\resources\app.asar\plugins\downloader\back.js:23:46)
    at Module._compile (node:internal/modules/cjs/loader:1141:14)
(Use `Youtube Music --trace-warnings ...` to show where the warning was created)
(node:6124) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 31)

Expected behavior

The app loads

Current behavior

The app fails to load

Version

Default

Anything else?

I isolated the origin of the problem to this line:

const package_json = JSON.parse(readFileSync(path.resolve(__dirname__, is_cjs ? '../package.json' : '../../package.json'), 'utf-8'));

this seems to not resolve in a built asar (which electron does)

and then the following lines throw:

runtime: 'node',
info: {
version: package_json.version,
bugs_url: package_json.bugs.url,
repo_url: package_json.homepage.split('#')[0]
},

Checklist

  • I am running the latest version.
  • I checked the documentation and found no answer.
  • I have searched the existing issues and made sure this is not a duplicate.
  • I have provided sufficient information.
@Araxeus Araxeus added the bug Something isn't working label Mar 22, 2023
@Araxeus
Copy link
Contributor Author

Araxeus commented Mar 22, 2023

@LuanRT We integrated this library in https://github.com/th-ch/youtube-music

Tests ran fine in dev mode, and it built fine, so the changes were merged

Now upon building the app, I suddenly encounter this error :S

This is kinda high priority, would love a quick solution thanks ♥

@absidue
Copy link
Collaborator

absidue commented Mar 22, 2023

If you are using a bundler like webpack, you can write your code with ES6 imports and use the web version, as long as you are only using YouTube.js in the renderer (the node version of YouTube.js needs linkedom as a DOM polyfill, which is not needed in web browsers or the Electron renderer process).

That's what we do for FreeTube, also comes with the addional benefit of a smaller app size.

https://github.com/FreeTubeApp/FreeTube/blob/development/_scripts/webpack.renderer.config.js#L137

@Araxeus
Copy link
Contributor Author

Araxeus commented Mar 22, 2023

We are not using a bundler, and are using YouTube.js from the main process
(unlike your app, we directly load youtube, so every bit of performance on the renderer is very important)

This definitely needs fixing anyway

@absidue
Copy link
Collaborator

absidue commented Mar 22, 2023

Seems like we look for performance in different areas.
I recommend bundling your code, instead of doing imports at runtime. require() is expensive and blocking, so you are likely taking a hit to your startup time, as Electron has to follow the require chain instead of just being able to load a single main.js file.

https://www.electronjs.org/docs/latest/tutorial/performance#7-bundle-your-code

@Araxeus
Copy link
Contributor Author

Araxeus commented Mar 22, 2023

I recommend bundling your code,

Thanks for the tip, but it has nothing to do with the issue here (or loading from renderer vs main) 😅

@LuanRT
Copy link
Owner

LuanRT commented Mar 22, 2023

This is interesting. I wonder what's happening to the package.json file for it to fail like that.

I'll set up a small Electron app to see if I can reproduce this. Note that I have no experience with Electron apps at all, so if anyone is able to help by doing some debugging too I'd appreciate.

Also, as absidue said, you can try other entry points the library exposes; web, web.agnostic, web.bundle, web.bundle.min and etc but I'm not sure if it'd work. So this definitely needs to be fixed.

@Araxeus
Copy link
Contributor Author

Araxeus commented Mar 22, 2023

This is interesting. I wonder what's happening to the package.json file for it to fail like that.

I think it's because the app is inside a app.asar - https://github.com/electron/asar file, so readFileSync fails

more info in https://www.electronjs.org/docs/latest/tutorial/asar-archives

you can try other entry points the library exposes; web, web.agnostic, web.bundle, web.bundle.min

I can't really since we are loading it from Node.js and not the web (Electron main process vs renderer process)

@Araxeus
Copy link
Contributor Author

Araxeus commented Mar 22, 2023

@LuanRT Ok sorry but I was completely wrong, it reads the package.json file correctly, but it's missing fields somehow...

{
  dirname: 'C:\\Users\\Araxeus\\AppData\\Local\\Programs\\youtube-music\\resources\\app.asar\\node_modules\\youtubei.js\\bundle',
  full_path: 'C:\\Users\\Araxeus\\AppData\\Local\\Programs\\youtube-music\\resources\\app.asar\\node_modules\\youtubei.js\\package.json',
  package_json: {
    name: 'youtubei.js',
    version: '3.1.1',
    description: "A wrapper around YouTube's private API. Supports YouTube, YouTube Music, YouTube Kids and YouTube Studio (WIP).",
    type: 'module',
    types: './dist/src/platform/lib.d.ts',
    typesVersions: { '*': [Object] },
    exports: {
      './bundle': './bundle/node.cjs',
      '.': [Object],
      './agnostic': [Object],
      './web': [Object],
      './web.bundle': [Object],
      './web.bundle.min': [Object]
    },
    author: 'LuanRT <[email protected]> (https://github.com/LuanRT)',
    funding: [ 'https://github.com/sponsors/LuanRT' ],
    directories: { test: './test', examples: './examples', dist: './dist' },
    repository: {
      type: 'git',
      url: 'git+https://github.com/LuanRT/YouTube.js.git'
    },
    license: 'MIT',
    dependencies: { jintr: '^0.4.1', linkedom: '^0.14.12', undici: '^5.19.1' },
    devDependencies: {
      '@types/jest': '^28.1.7',
      '@types/node': '^17.0.45',
      '@typescript-eslint/eslint-plugin': '^5.30.6',
      'cpy-cli': '^4.2.0',
      esbuild: '^0.14.49',
      eslint: '^8.19.0',
      'eslint-plugin-tsdoc': '^0.2.16',
      glob: '^8.0.3',
      jest: '^28.1.3',
      pbkit: '^0.0.59',
      replace: '^1.2.2',
      'ts-jest': '^28.0.8',
      typescript: '^4.9.5'
    },
    homepage: 'https://github.com/LuanRT/YouTube.js#readme'
  }
}

and then

runtime: 'node',
info: {
version: package_json.version,
bugs_url: package_json.bugs.url,
repo_url: package_json.homepage.split('#')[0]
},

Accesses package.bugs.url but package.bugs is undefined so it throws an error

@Araxeus
Copy link
Contributor Author

Araxeus commented Mar 22, 2023

This is extremely weird, I don't know what to think...

what could ever cause the package.json to get so short like that? 😣

EDIT: I manually unpacked the asar, and it seems the package.json is trimmed automatically somehow

this whole problem could be fixed by changing:

 runtime: 'node', 
 info: { 
   version: package_json.version, 
-  bugs_url: package_json.bugs.url,
+  bugs_url: package_json.bugs?.url,  
-  repo_url: package_json.homepage.split('#')[0] 
+  repo_url: package_json.homepage?.split('#')[0] 
}, 

(I have actually tested it, just adding a simple ? fixes everything)

Sorry for spamming a bit, but atleast there is a one line fix 😝

@Araxeus
Copy link
Contributor Author

Araxeus commented Mar 22, 2023

I've opened a simple PR which fixes this issue

@absidue
Copy link
Collaborator

absidue commented Mar 22, 2023

That only fixes the crash, it doesn't actually solve the fundemental issue of the properties not being there.

@LuanRT
Copy link
Owner

LuanRT commented Mar 22, 2023

@Araxeus
Do you know if the homepage field is always there? If it is, then it would be a good idea to use that as a fallback for the bugs url. Similar to what's being done in the repo_url field. This way, we could keep it as that field is used to tell the user to open an issue here when something goes wrong inside the library. Having it be undefined would most likely cause some confusion.

Anywho, it's still weird how the bug report URL is missing in package.json.

@Araxeus
Copy link
Contributor Author

Araxeus commented Mar 22, 2023

That only fixes the crash, it doesn't actually solve the fundemental issue of the properties not being there.

Good enough for me 😅


Anywho, it's still weird how the bug report URL is missing in package.json.

I have truly no idea what's trimming the package.json... it is very weird indeed


Do you know if the homepage field is always there?

It seems to be there, you can see the full package.json in my comment above


use that as a fallback for the bugs url.

What if the repo_url is also missing somehow?
Can we do it like this?

const repo_url = package_json.homepage?.split('#')[0];
....
 runtime: 'node', 
 info: { 
   version: package_json.version, 
   ...(repo_url ? { repo_url, bugs_url: `${repo_url}/issues` } : {})
 }, 

I'm assuming here that if repo_url is missing, then so is bugs_url (IMO a fair assumption)
if it's not good enough, maybe could instead do something like this:

const repo_url = package_json.homepage?.split('#')[0];
const bugs_url = package_json.bugs?.url;
....
 runtime: 'node', 
 info: { 
   version: package_json.version,
   repo_url: repo_url || "https://github.com/LuanRT/YouTube.js",
   bugs_url: bugs_url || repo_url ? `${repo_url}/issues` : "https://github.com/LuanRT/YouTube.js/issues"
 }, 

@Araxeus Araxeus changed the title 4.0.1 Errpr thrown in built Electron app 4.0.1 Error thrown in built Electron app Mar 22, 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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants