Skip to content

Commit

Permalink
feat!: Support detailed error objects in cli (twilio#108)
Browse files Browse the repository at this point in the history
Co-authored-by: Alec <amarcum@twilio.com>
Co-authored-by: Jennifer Mah <42650198+JenniferMah@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 8, 2021
1 parent 2d30565 commit f204fa3
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 8 deletions.
8 changes: 6 additions & 2 deletions src/base-commands/base-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@ class BaseCommand extends Command {

if (instanceOf(error, TwilioCliError)) {
// User/API errors
this.logger.error(error.message);
this.logger.debug(error.stack);
if (this.flags['cli-output-format'] === 'json') {
this.output(error);
} else {
this.logger.error(error.message);
this.logger.debug(error.stack);
}
this.exit(error.exitCode || 1);
} else {
// System errors
Expand Down
21 changes: 16 additions & 5 deletions src/services/cli-http-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,8 @@ class CliRequestClient {
this.logger.debug(`response.headers: ${JSON.stringify(response.headers)}`);

if (response.status < 200 || response.status >= 400) {
const parsed = response.data;
throw new TwilioCliError(
`Error code ${parsed.code} from Twilio: ${parsed.message}. See ${parsed.more_info} for more info.`,
parsed.code,
);
const { message, code, details } = this.formatErrorMessage(response.data);
throw new TwilioCliError(message, code, details);
}

return {
Expand Down Expand Up @@ -140,6 +137,20 @@ class CliRequestClient {
this.logger.debug(`User-Agent: ${options.headers['User-Agent']}`);
this.logger.debug('-- END Twilio API Request --');
}

/* eslint-disable camelcase */
// In the rare event parameters are missing, display a readable message
formatErrorMessage({ code, message, more_info, details }) {
const moreInfoMessage = more_info ? `See ${more_info} for more info.` : '';
const error = {
message: `Error code ${code || 'N/A'} from Twilio: ${message || 'No message provided'}. ${moreInfoMessage}`,
code,
details,
};

return error;
}
/* eslint-enable camelcase */
}

module.exports = CliRequestClient;
3 changes: 2 additions & 1 deletion src/services/error.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class TwilioCliError extends Error {
constructor(message, exitCode) {
constructor(message, exitCode, details = 'No details provided') {
super(message);
this.name = this.constructor.name;
this.exitCode = exitCode;
this.details = details;
}
}

Expand Down
13 changes: 13 additions & 0 deletions test/base-commands/base-command.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ describe('base-commands', () => {
expect(ctx.stderr).to.contain('oy!');
});

test
.twilioCliEnv()
.stdout()
.do(async (ctx) => {
ctx.testCmd = new BaseCommand(['-o', 'json'], ctx.fakeConfig);
await ctx.testCmd.run();
await ctx.testCmd.catch(new TwilioCliError('oh no', 1, { errors: [{ message: 'oh no' }] }));
})
.exit(1)
.it('can correctly display error details', (ctx) => {
expect(ctx.stdout).to.contain(`"message": "oh no"`);
});

test
.twilioCliEnv()
.do((ctx) => {
Expand Down

0 comments on commit f204fa3

Please sign in to comment.