Skip to content

Commit

Permalink
fix(list): include errors in standard output
Browse files Browse the repository at this point in the history
  • Loading branch information
imhoffd committed Jul 12, 2019
1 parent e213e25 commit 9ceb343
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 46 deletions.
13 changes: 8 additions & 5 deletions src/android/list.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
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<void> {
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<Targets> {
const sdk = await getSDK();

const errors: Exception<string>[] = [];
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 [];
}
})(),
(async () => {
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 };
}
6 changes: 5 additions & 1 deletion src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { stringify } from './utils/json';

export const enum ExitCode {
GENERAL = 1,
}

export class Exception<T extends string, D = object> 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);
}

Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -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');

Expand Down Expand Up @@ -41,7 +41,7 @@ export async function run(): Promise<void> {
}
} 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));
}
}
12 changes: 7 additions & 5 deletions src/ios/list.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
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<Targets> {
const errors: Exception<string>[] = [];
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 [];
}
})(),
Expand All @@ -26,13 +28,13 @@ export async function list(args: readonly string[]): Promise<Targets> {
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 {
Expand Down
38 changes: 10 additions & 28 deletions src/list.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
let iosError: Error | undefined;
let androidError: Error | undefined;

const [ios, android] = await Promise.all([
(async (): Promise<Targets | undefined> => {
const [ ios, android ] = await Promise.all([
(async (): Promise<Targets> => {
const cmd = await import('./ios/list');

try {
return await cmd.list(args);
} catch (e) {
iosError = e;
}
return cmd.list(args);
})(),
(async (): Promise<Targets | undefined> => {
(async (): Promise<Targets> => {
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)}
`);
}
Expand Down
16 changes: 11 additions & 5 deletions src/utils/list.ts
Original file line number Diff line number Diff line change
@@ -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<string>[];
}

export interface Target {
Expand All @@ -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');
Expand All @@ -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) {
Expand Down

0 comments on commit 9ceb343

Please sign in to comment.