Skip to content

Commit 9ceb343

Browse files
committed
fix(list): include errors in standard output
1 parent e213e25 commit 9ceb343

File tree

6 files changed

+43
-46
lines changed

6 files changed

+43
-46
lines changed

src/android/list.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
1-
import { serializeError } from '../errors';
1+
import { Exception } from '../errors';
22
import { Targets, formatTargets } from '../utils/list';
33

44
import { getDeviceTargets, getVirtualTargets } from './utils/list';
55
import { getSDK } from './utils/sdk';
66

77
export async function run(args: readonly string[]): Promise<void> {
8-
process.stdout.write(`\n${formatTargets(args, await list(args))}\n`);
8+
const targets = await list(args);
9+
process.stdout.write(`\n${formatTargets(args, targets)}\n`);
910
}
1011

1112
export async function list(args: readonly string[]): Promise<Targets> {
1213
const sdk = await getSDK();
14+
15+
const errors: Exception<string>[] = [];
1316
const [ devices, virtualDevices ] = await Promise.all([
1417
(async () => {
1518
try {
1619
return await getDeviceTargets(sdk);
1720
} catch (e) {
18-
process.stderr.write(`Error with Android device targets: ${serializeError(e)}`);
21+
errors.push(e);
1922
return [];
2023
}
2124
})(),
2225
(async () => {
2326
try {
2427
return await getVirtualTargets(sdk);
2528
} catch (e) {
26-
process.stderr.write(`Error with Android virtual targets: ${serializeError(e)}`);
29+
errors.push(e);
2730
return [];
2831
}
2932
})(),
3033
]);
3134

32-
return { devices, virtualDevices };
35+
return { devices, virtualDevices, errors };
3336
}

src/errors.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { stringify } from './utils/json';
22

3+
export const enum ExitCode {
4+
GENERAL = 1,
5+
}
6+
37
export class Exception<T extends string, D = object> extends Error implements NodeJS.ErrnoException {
4-
constructor(readonly message: string, readonly code?: T, readonly exitCode = 1, readonly data?: D) {
8+
constructor(readonly message: string, readonly code?: T, readonly exitCode = ExitCode.GENERAL, readonly data?: D) {
59
super(message);
610
}
711

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as Debug from 'debug';
22
import * as path from 'path';
33

4-
import { CLIException, ERR_BAD_INPUT, Exception, serializeError } from './errors';
4+
import { CLIException, ERR_BAD_INPUT, Exception, ExitCode, serializeError } from './errors';
55

66
const debug = Debug('native-run');
77

@@ -41,7 +41,7 @@ export async function run(): Promise<void> {
4141
}
4242
} catch (e) {
4343
debug('Caught fatal error: %O', e);
44-
process.exitCode = e instanceof Exception ? e.exitCode : 1;
44+
process.exitCode = e instanceof Exception ? e.exitCode : ExitCode.GENERAL;
4545
process.stdout.write(serializeError(e));
4646
}
4747
}

src/ios/list.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
import { DeviceValues } from 'node-ioslib';
22

3-
import { serializeError } from '../errors';
3+
import { Exception } from '../errors';
44
import { Target, Targets, formatTargets } from '../utils/list';
55

66
import { getConnectedDevices } from './utils/device';
77
import { Simulator, getSimulators } from './utils/simulator';
88

99
export async function run(args: readonly string[]): Promise<void> {
10-
process.stdout.write(`\n${formatTargets(args, await list(args))}\n`);
10+
const targets = await list(args);
11+
process.stdout.write(`\n${formatTargets(args, targets)}\n`);
1112
}
1213

1314
export async function list(args: readonly string[]): Promise<Targets> {
15+
const errors: Exception<string>[] = [];
1416
const [ devices, virtualDevices ] = await Promise.all([
1517
(async () => {
1618
try {
1719
const devices = await getConnectedDevices();
1820
return devices.map(deviceToTarget);
1921
} catch (e) {
20-
process.stderr.write(`Error with iOS device targets: ${serializeError(e)}`);
22+
errors.push(e);
2123
return [];
2224
}
2325
})(),
@@ -26,13 +28,13 @@ export async function list(args: readonly string[]): Promise<Targets> {
2628
const simulators = await getSimulators();
2729
return simulators.map(simulatorToTarget);
2830
} catch (e) {
29-
process.stderr.write(`Error with iOS virtual targets: ${serializeError(e)}`);
31+
errors.push(e);
3032
return [];
3133
}
3234
})(),
3335
]);
3436

35-
return { devices, virtualDevices };
37+
return { devices, virtualDevices, errors };
3638
}
3739

3840
function deviceToTarget(device: DeviceValues): Target {

src/list.ts

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,31 @@
1-
import { serializeError } from './errors';
21
import { stringify } from './utils/json';
32
import { Targets, formatTargets } from './utils/list';
43

54
export async function run(args: readonly string[]): Promise<void> {
6-
let iosError: Error | undefined;
7-
let androidError: Error | undefined;
8-
9-
const [ios, android] = await Promise.all([
10-
(async (): Promise<Targets | undefined> => {
5+
const [ ios, android ] = await Promise.all([
6+
(async (): Promise<Targets> => {
117
const cmd = await import('./ios/list');
12-
13-
try {
14-
return await cmd.list(args);
15-
} catch (e) {
16-
iosError = e;
17-
}
8+
return cmd.list(args);
189
})(),
19-
(async (): Promise<Targets | undefined> => {
10+
(async (): Promise<Targets> => {
2011
const cmd = await import('./android/list');
21-
22-
try {
23-
return await cmd.list(args);
24-
} catch (e) {
25-
androidError = e;
26-
}
12+
return cmd.list(args);
2713
})(),
2814
]);
2915

30-
if (iosError || androidError) {
31-
process.exitCode = 1;
32-
}
33-
3416
if (args.includes('--json')) {
35-
process.stdout.write(stringify({ ios, iosError, android, androidError }));
17+
process.stdout.write(stringify({ ios, android }));
3618
} else {
3719
process.stdout.write(`
38-
iOS ${iosError ? '(!)' : ''}
20+
iOS
3921
---
4022
41-
${ios ? formatTargets(args, ios) : serializeError(iosError)}
23+
${formatTargets(args, ios)}
4224
43-
Android ${androidError ? '(!)' : ''}
25+
Android
4426
-------
4527
46-
${android ? formatTargets(args, android) : serializeError(androidError)}
28+
${formatTargets(args, android)}
4729
4830
`);
4931
}

src/utils/list.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { CLIException, ERR_BAD_INPUT } from '../errors';
1+
import { CLIException, ERR_BAD_INPUT, Exception, serializeError } from '../errors';
22

33
import { stringify } from './json';
44

55
export interface Targets {
66
readonly devices: readonly Target[];
77
readonly virtualDevices: readonly Target[];
8+
readonly errors: readonly Exception<string>[];
89
}
910

1011
export interface Target {
@@ -17,7 +18,7 @@ export interface Target {
1718
}
1819

1920
export function formatTargets(args: readonly string[], targets: Targets): string {
20-
const { devices, virtualDevices } = targets;
21+
const { devices, virtualDevices, errors } = targets;
2122

2223
const virtualOnly = args.includes('--virtual');
2324
const devicesOnly = args.includes('--device');
@@ -29,16 +30,21 @@ export function formatTargets(args: readonly string[], targets: Targets): string
2930
if (args.includes('--json')) {
3031
let result;
3132
if (virtualOnly) {
32-
result = { virtualDevices };
33+
result = { virtualDevices, errors };
3334
} else if (devicesOnly) {
34-
result = { devices };
35+
result = { devices, errors };
3536
} else {
36-
result = { devices, virtualDevices };
37+
result = { devices, virtualDevices, errors };
3738
}
3839
return stringify(result);
3940
}
4041

4142
let output = '';
43+
44+
if (errors.length > 0) {
45+
output += `Errors (!):\n\n${errors.map(e => ` ${serializeError(e)}`)}\n`;
46+
}
47+
4248
if (!virtualOnly) {
4349
output += printTargets('Connected Device', devices);
4450
if (devicesOnly) {

0 commit comments

Comments
 (0)