From 5cb5d9e2cb2b45c7e14b87f17a44488eea97433b Mon Sep 17 00:00:00 2001 From: Niklas Higi Date: Sat, 26 Jun 2021 18:40:05 +0200 Subject: [PATCH] Implement `UserError` class for errors that don't require a stack trace --- src/cli.ts | 6 ++++++ src/tasks/check-prerequisites.ts | 5 +++-- src/utils/get-java-version.ts | 5 +++-- src/utils/user-error.ts | 10 ++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 src/utils/user-error.ts 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 + } +}