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

Issue with _withEnv implementation within electron environment #84

Open
strazzere opened this issue Mar 4, 2023 · 0 comments
Open

Issue with _withEnv implementation within electron environment #84

strazzere opened this issue Mar 4, 2023 · 0 comments

Comments

@strazzere
Copy link
Contributor

This took quiet a while to track down and implement a work around - though I must admit, it feels like there should be another way to do this. Please take this report with a grain of salt as I may be missing the actual underlying issue as it only reproduces in some environments.

While attempting to do a simple adb operation like this following;

 const { Adb } = require("promise-android-tools")
 adb = new Adb({serialno:"12345" })
 await adb.push(['tsconfig.json'], '/data/local/tmp/derp')

The package would spit out a TypeError: Illegal Instruction on the line this.signal.throwIfAborted() inside Tool._withEnv.

This does not reproduce when running solely in a node environment, the this object appears fine. However in the electron environment where it fails, the this object appears to be a "less than deep" clone, or the this context appears to get mangled somehow - this part is a bit unclear to me.

I believe this is based on how Object.create doesn't actually run the constructor. Tested a few other methods for deep cloning the object (Object.assign({}, this), { ... this}, ...) - thought none of them seemed to solve them. Since the type is unpredictable (Adb, FastBoot, Heimdall) it seemed best to try to reflectively call this's own type constructor and just pass this to it. This resulted in the following patch;

diff --git a/src/tool.ts b/src/tool.ts
index c19b017..c1b678b 100644
--- a/src/tool.ts
+++ b/src/tool.ts
@@ -227,7 +227,8 @@ export abstract class Tool extends Interface {
 
   /** returns clone with variation in env vars */
   public _withEnv(env: NodeJS.ProcessEnv): this {
-    const ret = Object.create(this);
+    // @ts-ignore-next-line
+    const ret = new this.constructor(this);
     ret.extraEnv = { ...this.extraEnv };
     for (const key in env) {
       if (Object.hasOwnProperty.call(env, key)) {

This does work for my usecase, and seemingly all other spawn commands I tried, though I honestly hate it due to the ts-ignore.

Hoping to potentially learn something here if anyone knows a better way to fix this issue, or if maybe I'm completely misunderstanding this issue. Whatever the solution, it would likely need to be applied to a few other spots which utilize the Object.create(this) pattern.

If the solution I found above seems the best fitting, I can always draft a PR to fix this and other instance with a bit of a commented explanation.

Cheers!

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

1 participant