From 9ceb34394ead71f13fc7a63d7ec67ed2e605f6ef Mon Sep 17 00:00:00 2001 From: Daniel Imhoff Date: Thu, 11 Jul 2019 18:03:45 -0500 Subject: [PATCH] fix(list): include errors in standard output --- src/android/list.ts | 13 ++++++++----- src/errors.ts | 6 +++++- src/index.ts | 4 ++-- src/ios/list.ts | 12 +++++++----- src/list.ts | 38 ++++++++++---------------------------- src/utils/list.ts | 16 +++++++++++----- 6 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/android/list.ts b/src/android/list.ts index a0748ce..445fdef 100644 --- a/src/android/list.ts +++ b/src/android/list.ts @@ -1,21 +1,24 @@ -import { serializeError } from '../errors'; +import { Exception } from '../errors'; import { Targets, formatTargets } from '../utils/list'; import { getDeviceTargets, getVirtualTargets } from './utils/list'; import { getSDK } from './utils/sdk'; export async function run(args: readonly string[]): Promise { - process.stdout.write(`\n${formatTargets(args, await list(args))}\n`); + const targets = await list(args); + process.stdout.write(`\n${formatTargets(args, targets)}\n`); } export async function list(args: readonly string[]): Promise { const sdk = await getSDK(); + + const errors: Exception[] = []; const [ devices, virtualDevices ] = await Promise.all([ (async () => { try { return await getDeviceTargets(sdk); } catch (e) { - process.stderr.write(`Error with Android device targets: ${serializeError(e)}`); + errors.push(e); return []; } })(), @@ -23,11 +26,11 @@ export async function list(args: readonly string[]): Promise { try { return await getVirtualTargets(sdk); } catch (e) { - process.stderr.write(`Error with Android virtual targets: ${serializeError(e)}`); + errors.push(e); return []; } })(), ]); - return { devices, virtualDevices }; + return { devices, virtualDevices, errors }; } diff --git a/src/errors.ts b/src/errors.ts index f2acd5c..86e4047 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,7 +1,11 @@ import { stringify } from './utils/json'; +export const enum ExitCode { + GENERAL = 1, +} + export class Exception extends Error implements NodeJS.ErrnoException { - constructor(readonly message: string, readonly code?: T, readonly exitCode = 1, readonly data?: D) { + constructor(readonly message: string, readonly code?: T, readonly exitCode = ExitCode.GENERAL, readonly data?: D) { super(message); } diff --git a/src/index.ts b/src/index.ts index 8d8cb77..1c7f6be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import * as Debug from 'debug'; import * as path from 'path'; -import { CLIException, ERR_BAD_INPUT, Exception, serializeError } from './errors'; +import { CLIException, ERR_BAD_INPUT, Exception, ExitCode, serializeError } from './errors'; const debug = Debug('native-run'); @@ -41,7 +41,7 @@ export async function run(): Promise { } } catch (e) { debug('Caught fatal error: %O', e); - process.exitCode = e instanceof Exception ? e.exitCode : 1; + process.exitCode = e instanceof Exception ? e.exitCode : ExitCode.GENERAL; process.stdout.write(serializeError(e)); } } diff --git a/src/ios/list.ts b/src/ios/list.ts index c10b9ba..00d1eeb 100644 --- a/src/ios/list.ts +++ b/src/ios/list.ts @@ -1,23 +1,25 @@ import { DeviceValues } from 'node-ioslib'; -import { serializeError } from '../errors'; +import { Exception } from '../errors'; import { Target, Targets, formatTargets } from '../utils/list'; import { getConnectedDevices } from './utils/device'; import { Simulator, getSimulators } from './utils/simulator'; export async function run(args: readonly string[]): Promise { - process.stdout.write(`\n${formatTargets(args, await list(args))}\n`); + const targets = await list(args); + process.stdout.write(`\n${formatTargets(args, targets)}\n`); } export async function list(args: readonly string[]): Promise { + const errors: Exception[] = []; const [ devices, virtualDevices ] = await Promise.all([ (async () => { try { const devices = await getConnectedDevices(); return devices.map(deviceToTarget); } catch (e) { - process.stderr.write(`Error with iOS device targets: ${serializeError(e)}`); + errors.push(e); return []; } })(), @@ -26,13 +28,13 @@ export async function list(args: readonly string[]): Promise { const simulators = await getSimulators(); return simulators.map(simulatorToTarget); } catch (e) { - process.stderr.write(`Error with iOS virtual targets: ${serializeError(e)}`); + errors.push(e); return []; } })(), ]); - return { devices, virtualDevices }; + return { devices, virtualDevices, errors }; } function deviceToTarget(device: DeviceValues): Target { diff --git a/src/list.ts b/src/list.ts index 490692f..8a3db11 100644 --- a/src/list.ts +++ b/src/list.ts @@ -1,49 +1,31 @@ -import { serializeError } from './errors'; import { stringify } from './utils/json'; import { Targets, formatTargets } from './utils/list'; export async function run(args: readonly string[]): Promise { - let iosError: Error | undefined; - let androidError: Error | undefined; - - const [ios, android] = await Promise.all([ - (async (): Promise => { + const [ ios, android ] = await Promise.all([ + (async (): Promise => { const cmd = await import('./ios/list'); - - try { - return await cmd.list(args); - } catch (e) { - iosError = e; - } + return cmd.list(args); })(), - (async (): Promise => { + (async (): Promise => { const cmd = await import('./android/list'); - - try { - return await cmd.list(args); - } catch (e) { - androidError = e; - } + return cmd.list(args); })(), ]); - if (iosError || androidError) { - process.exitCode = 1; - } - if (args.includes('--json')) { - process.stdout.write(stringify({ ios, iosError, android, androidError })); + process.stdout.write(stringify({ ios, android })); } else { process.stdout.write(` -iOS ${iosError ? '(!)' : ''} +iOS --- -${ios ? formatTargets(args, ios) : serializeError(iosError)} +${formatTargets(args, ios)} -Android ${androidError ? '(!)' : ''} +Android ------- -${android ? formatTargets(args, android) : serializeError(androidError)} +${formatTargets(args, android)} `); } diff --git a/src/utils/list.ts b/src/utils/list.ts index c20cd94..6764a46 100644 --- a/src/utils/list.ts +++ b/src/utils/list.ts @@ -1,10 +1,11 @@ -import { CLIException, ERR_BAD_INPUT } from '../errors'; +import { CLIException, ERR_BAD_INPUT, Exception, serializeError } from '../errors'; import { stringify } from './json'; export interface Targets { readonly devices: readonly Target[]; readonly virtualDevices: readonly Target[]; + readonly errors: readonly Exception[]; } export interface Target { @@ -17,7 +18,7 @@ export interface Target { } export function formatTargets(args: readonly string[], targets: Targets): string { - const { devices, virtualDevices } = targets; + const { devices, virtualDevices, errors } = targets; const virtualOnly = args.includes('--virtual'); const devicesOnly = args.includes('--device'); @@ -29,16 +30,21 @@ export function formatTargets(args: readonly string[], targets: Targets): string if (args.includes('--json')) { let result; if (virtualOnly) { - result = { virtualDevices }; + result = { virtualDevices, errors }; } else if (devicesOnly) { - result = { devices }; + result = { devices, errors }; } else { - result = { devices, virtualDevices }; + result = { devices, virtualDevices, errors }; } return stringify(result); } let output = ''; + + if (errors.length > 0) { + output += `Errors (!):\n\n${errors.map(e => ` ${serializeError(e)}`)}\n`; + } + if (!virtualOnly) { output += printTargets('Connected Device', devices); if (devicesOnly) {