diff --git a/src/cli.ts b/src/cli.ts index 13e7be5..4bd30ba 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,6 +10,7 @@ import { patchXapkBundle, patchApksBundle } from './patch-app-bundle' import Apktool from './tools/apktool' import UberApkSigner from './tools/uber-apk-signer' import Tool from './tools/tool' +import UserError from './utils/user-error' export type TaskOptions = { inputPath: string @@ -131,7 +132,12 @@ async function main() { } function getErrorMessage(error: PatchingError, { tmpDir }: { tmpDir: string }) { + // User errors can be shown without a stack trace + if (error instanceof UserError) return error.message + + // Errors from commands can also be shown without a stack trace if (error.all) return formatCommandError(error.all, { tmpDir }) + return error.stack } diff --git a/src/tasks/check-prerequisites.ts b/src/tasks/check-prerequisites.ts index 69f4331..f8c9398 100644 --- a/src/tasks/check-prerequisites.ts +++ b/src/tasks/check-prerequisites.ts @@ -3,6 +3,7 @@ import Listr = require('listr') import { TaskOptions } from '../cli' import getJavaVersion from '../utils/get-java-version' +import UserError from '../utils/user-error' import downloadTools from './download-tools' const MIN_NODE_VERSION = 14 @@ -49,14 +50,14 @@ async function ensureZipUlitiesAvailable() { await execa('unzip', ['-v']) await execa('zip', ['-v']) } catch { - throw new Error( + throw new UserError( 'apk-mitm requires the commands "unzip" and "zip" to be installed when patching App Bundles.' + " Make sure they're both installed and try again!", ) } } -class VersionError extends Error { +class VersionError extends UserError { constructor(tool: string, minVersion: number, currentVersion: number) { super( `apk-mitm requires at least ${tool} ${minVersion} to work and you seem to be using ${tool} ${currentVersion}.` + diff --git a/src/utils/get-java-version.ts b/src/utils/get-java-version.ts index 7d3f23e..515a8c6 100644 --- a/src/utils/get-java-version.ts +++ b/src/utils/get-java-version.ts @@ -1,4 +1,5 @@ import execa = require('execa') +import UserError from './user-error' /** Returns the major version of the system's default Java installation. */ export default async function getJavaVersion() { @@ -7,13 +8,13 @@ export default async function getJavaVersion() { const majorVersionString = stderr.match(JAVA_VERSION_PATTERN)?.groups?.major if (!majorVersionString) { const message = `Could not extract Java major version from "java -version" output!\n${stderr}` - throw new Error(message) + throw new UserError(message) } return parseInt(majorVersionString) } catch (error) { if (error.code === 'ENOENT') - throw new Error( + throw new UserError( 'No "java" executable could be found!' + ' Make sure that Java is installed and available in your PATH.', ) diff --git a/src/utils/user-error.ts b/src/utils/user-error.ts new file mode 100644 index 0000000..e40367f --- /dev/null +++ b/src/utils/user-error.ts @@ -0,0 +1,10 @@ +/** + * Class for custom errors that can be shown directly to users of the CLI + * without displaying the entire stack trace. + */ +export default class UserError extends Error { + constructor(message: string) { + super(message) + this.name = UserError.name + } +}