Skip to content

Commit

Permalink
improvement: better error & cancellation handling, region choice changed
Browse files Browse the repository at this point in the history
region choice is changed from defaultRegions to allRegions
  • Loading branch information
hoonoh committed Oct 21, 2019
1 parent b7c9d16 commit 079e8e5
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 25 deletions.
9 changes: 7 additions & 2 deletions src/cli-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ type Answer2 = {

export type Answers = Answer1 & Answer2;

const onCancel = (): void => {
console.log('aborted');
process.exit();
};

export const ui = async (): Promise<Answers | undefined> => {
try {
const question1 = [
Expand Down Expand Up @@ -62,7 +67,7 @@ export const ui = async (): Promise<Answers | undefined> => {
},
];

const answer1: Answer1 = await prompt(question1);
const answer1: Answer1 = await prompt(question1, { onCancel });

const familyTypePreSelectedSet = new Set<InstanceFamilyType>();
const sizePreSelectedSet = new Set<InstanceSize>();
Expand Down Expand Up @@ -162,7 +167,7 @@ export const ui = async (): Promise<Answers | undefined> => {
},
];

const answer2: Answer2 = await prompt(question2);
const answer2: Answer2 = await prompt(question2, { onCancel });

return { ...answer1, ...answer2 };
} catch (error) {
Expand Down
6 changes: 3 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
ProductDescription,
productDescriptionWildcards,
} from './product-description';
import { defaultRegions, Region } from './regions';
import { allRegions, Region } from './regions';

export const main = (argvInput?: string[]): Promise<void> =>
new Promise((res, rej): void => {
Expand All @@ -32,7 +32,7 @@ export const main = (argvInput?: string[]): Promise<void> =>
alias: 'r',
describe: 'AWS regions.',
type: 'array',
choices: defaultRegions,
choices: allRegions,
string: true,
},
instanceType: {
Expand Down Expand Up @@ -298,7 +298,7 @@ export const main = (argvInput?: string[]): Promise<void> =>
});
y.parse(params);
} else {
console.log('aborted');
console.log('Unexpected UI answers. aborted.');
}
});
} else {
Expand Down
77 changes: 57 additions & 20 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,23 @@ const sortSpotPrice = (p1: EC2.SpotPrice, p2: EC2.SpotPrice): number => {
return rtn;
};

const getEc2SpotPrice = async (options: {
class Ec2SpotPriceError extends Error {
constructor(message: string, region: Region, code: string) {
super(message);
this.name = 'Ec2SpotPriceError';
this.region = region;
this.code = code;
Object.setPrototypeOf(this, Ec2SpotPriceError.prototype);
}

region: string;
instanceTypes?: string[];

code: string;
}

const getEc2SpotPrice = async (options: {
region: Region;
instanceTypes?: InstanceType[];
productDescriptions?: ProductDescription[];
accessKeyId?: string;
secretAccessKey?: string;
Expand Down Expand Up @@ -82,10 +96,14 @@ const getEc2SpotPrice = async (options: {
rtn = list.filter(history => history.InstanceType).sort(sortSpotPrice);
}
} catch (error) {
console.error(
'unexpected getEc2SpotPrice error.',
JSON.stringify({ region, instanceTypes, productDescriptions, error }, null, 2),
);
if (error && error.code && (error.code === 'AuthFailure' || error.code === 'OptInRequired')) {
throw new Ec2SpotPriceError(error.message, region, error.code);
} else {
console.error(
'unexpected getEc2SpotPrice error.',
JSON.stringify({ region, instanceTypes, productDescriptions, error }, null, 2),
);
}
}

return rtn;
Expand Down Expand Up @@ -140,25 +158,44 @@ export const getGlobalSpotPrices = async (options?: {
}
}

const spinner = ora({
text: 'Waiting for data to be retrieved...',
discardStdin: false,
}).start();
let spinner: ora.Ora | undefined;
let spinnerText: string | undefined;
if (!silent && process.env.NODE_ENV !== 'test') {
spinner = ora({
text: 'Waiting for data to be retrieved...',
discardStdin: false,
}).start();
}

await Promise.all(
regions.map(async region => {
const regionsPrices = await getEc2SpotPrice({
region,
instanceTypes,
productDescriptions,
accessKeyId,
secretAccessKey,
});
rtn = [...rtn, ...regionsPrices];
if (!silent) spinner.text = `Retrieved data from ${region}...`;
try {
const regionsPrices = await getEc2SpotPrice({
region,
instanceTypes,
productDescriptions,
accessKeyId,
secretAccessKey,
});
rtn = [...rtn, ...regionsPrices];
if (spinner) {
spinnerText = `Retrieved data from ${region}...`;
spinner.text = spinnerText;
}
} catch (error) {
if (error instanceof Ec2SpotPriceError && spinner) {
spinner.fail(`Failed to retrieve data from ${error.region}. (${error.code})`);
spinner = ora({
text: spinnerText || spinner.text,
discardStdin: false,
}).start();
} else {
console.error(error);
}
}
}),
);
if (!silent) spinner.succeed('All data retrieved!').stop();
if (spinner) spinner.succeed('All data retrieved!').stop();

rtn = rtn.reduce(
(list, cur) => {
Expand Down

0 comments on commit 079e8e5

Please sign in to comment.