tweaselORG / appstraction

An abstraction layer for common instrumentation functions (e.g. installing and starting apps, setting preferences, etc.) on Android and iOS.
MIT License
4 stars 1 forks source link

Android: Errors in `startApp()` cannot be caught #101

Closed baltpeter closed 11 months ago

baltpeter commented 1 year ago

I noticed this with com.anysoftkeyboard.languagepack.german in https://github.com/tweaselORG/meta/issues/16. The app is just a keyboard with no main activity that could be started, which is why startApp() fails:

/home/benni/coding/JS/tweasel/experiments/cert-pinning-bypass/node_modules/execa/lib/error.js:59
        error = new Error(message);
                ^

Error: Command failed with exit code 252: /home/benni/.cache/andromatic/platform-tools/adb shell monkey -p com.anysoftkeyboard.languagepack.german -v 1 --dbg-no-events
args: [-p, com.anysoftkeyboard.languagepack.german, -v, 1, --dbg-no-events]
 arg: "-p"
 arg: "com.anysoftkeyboard.languagepack.german"
 arg: "-v"
 arg: "1"
 arg: "--dbg-no-events"
data="com.anysoftkeyboard.languagepack.german"
  bash arg: -p
  bash arg: com.anysoftkeyboard.languagepack.german
  bash arg: -v
  bash arg: 1
  bash arg: --dbg-no-events
:Monkey: seed=1687131772333 count=1
:AllowPackage: com.anysoftkeyboard.languagepack.german
:IncludeCategory: android.intent.category.LAUNCHER
:IncludeCategory: android.intent.category.MONKEY
** No activities found to run, monkey aborted.
    at makeError (/home/benni/coding/JS/tweasel/experiments/cert-pinning-bypass/node_modules/execa/lib/error.js:59:11)
    at handlePromise (/home/benni/coding/JS/tweasel/experiments/cert-pinning-bypass/node_modules/execa/index.js:124:26)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  shortMessage: 'Command failed with exit code 252: /home/benni/.cache/andromatic/platform-tools/adb shell monkey -p com.anysoftkeyboard.languagepack.german -v 1 --dbg-no-events',
  command: '/home/benni/.cache/andromatic/platform-tools/adb shell monkey -p com.anysoftkeyboard.languagepack.german -v 1 --dbg-no-events',
  escapedCommand: '"/home/benni/.cache/andromatic/platform-tools/adb" shell monkey -p com.anysoftkeyboard.languagepack.german -v 1 --dbg-no-events',
  exitCode: 252,
  signal: undefined,
  signalDescription: undefined,
  stdout: '  bash arg: -p\n' +
    '  bash arg: com.anysoftkeyboard.languagepack.german\n' +
    '  bash arg: -v\n' +
    '  bash arg: 1\n' +
    '  bash arg: --dbg-no-events\n' +
    ':Monkey: seed=1687131772333 count=1\n' +
    ':AllowPackage: com.anysoftkeyboard.languagepack.german\n' +
    ':IncludeCategory: android.intent.category.LAUNCHER\n' +
    ':IncludeCategory: android.intent.category.MONKEY\n' +
    '** No activities found to run, monkey aborted.',
  stderr: 'args: [-p, com.anysoftkeyboard.languagepack.german, -v, 1, --dbg-no-events]\n' +
    ' arg: "-p"\n' +
    ' arg: "com.anysoftkeyboard.languagepack.german"\n' +
    ' arg: "-v"\n' +
    ' arg: "1"\n' +
    ' arg: "--dbg-no-events"\n' +
    'data="com.anysoftkeyboard.languagepack.german"',
  failed: true,
  timedOut: false,
  isCanceled: false,
  killed: false
}

So far, so expected. However, my startApp() call is in a try-catch and the error wasn't caught. I'm assuming that's because we're instantiating the execa promise but not awaiting it.

zner0L commented 1 year ago

Why are we not awaiting it, though? The process exits after the app has been started.

baltpeter commented 1 year ago

To be symmetric with objection. We could change it for the monkey command, but then we'd have to implement something for objection anyway. (Unless the result from https://github.com/tweaselORG/meta/issues/16 is that we want to switch to something else).

zner0L commented 1 year ago

I don’t know how this would look like. We can not expect a try {} catch {} to catch errors asynchronously in the main thread. What we can do is not reject in execa. But this way, errors might not stop the execution, which we might want. These errors can only be handled unsynchronously.

zner0L commented 1 year ago

We could try to use a cancellation token or something similar, but this is harder than it looks. We cannot do much in appstraction, this has to happen mostly in the implementation code. Though we could return an AbortController in startApp.

baltpeter commented 1 year ago

Let's wait for a decision of whether we'll continue using objection in the first place before we put more work into this. I just wanted to note it.