From 075aa23bf40fbd663408802be286437cf4784eb3 Mon Sep 17 00:00:00 2001 From: childish-sambino Date: Fri, 15 May 2020 09:12:40 -0500 Subject: [PATCH] feat: look through plugin pjson for an issue URL (#87) Rather than have the twilio-cli GitHub issues link used for all uncaught exceptions, use that of the plugin for plugin commands. This change will attempt to find the plugin bugs/homepage/repo URL when a plugin command extending our `BaseCommand` throws an uncaught exception. If found, it will be used as part of the error message. Otherwise, it will fallback to use the standard twilio-cli URL. --- src/base-commands/base-command.js | 17 +++++++++++++--- src/services/messaging/help-messages.js | 4 ---- src/services/messaging/templates.js | 8 ++++---- src/services/require-install.js | 2 +- test/base-commands/base-command.test.js | 26 +++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/base-commands/base-command.js b/src/base-commands/base-command.js index 5923126b..898ceb11 100644 --- a/src/base-commands/base-command.js +++ b/src/base-commands/base-command.js @@ -1,11 +1,12 @@ const { Command, flags } = require('@oclif/command'); const { CLIError } = require('@oclif/errors'); +const pkg = require('../../package.json'); +const MessageTemplates = require('../services/messaging/templates'); const { Config, ConfigData } = require('../services/config'); const { TwilioCliError } = require('../services/error'); -const { UNEXPECTED_ERROR } = require('../services/messaging/help-messages'); const { logger, LoggingLevel } = require('../services/messaging/logging'); const { OutputFormats } = require('../services/output-formats'); -const { requireInstall } = require('../services/require-install'); +const { getCommandPlugin, requireInstall } = require('../services/require-install'); const { SecureStorage } = require('../services/secure-storage'); let inquirer; // We'll lazy-load this only when it's needed. @@ -63,13 +64,23 @@ class BaseCommand extends Command { this.exit(error.exitCode || 1); } else { // System errors - this.logger.error(UNEXPECTED_ERROR); + const plugin = getCommandPlugin(this); + this.logger.error(MessageTemplates.unexpectedError({ url: this.getIssueUrl(plugin) })); this.logger.debug(error.message); this.logger.debug(error.stack); this.exit(1); } } + getIssueUrl(plugin) { + const getPropertyUrl = value => value && (value.url || value); + const getPackageUrl = pjson => getPropertyUrl(pjson.bugs) || getPropertyUrl(pjson.homepage) || getPropertyUrl(pjson.repository); + + // If we found the plugin and an issue URL for it, use it. Otherwise + // fallback to our own issue URL. + return (plugin && getPackageUrl(plugin.pjson)) || getPackageUrl(pkg); + } + /** * Drops the week day and timezone name from the result of Date.toString(). * diff --git a/src/services/messaging/help-messages.js b/src/services/messaging/help-messages.js index a5119df4..b7350508 100644 --- a/src/services/messaging/help-messages.js +++ b/src/services/messaging/help-messages.js @@ -13,10 +13,6 @@ TWILIO_AUTH_TOKEN = your Auth Token from twil.io/console Once these environment variables are set, a ${CLI_NAME} profile is not required to move forward with installation.`; -exports.UNEXPECTED_ERROR = `${CLI_NAME} encountered an unexpected error. \ -To report this issue, execute the command with the "-l debug" flag, then copy the output to a new issue here: \ -https://github.com/twilio/twilio-cli/issues`; - exports.NETWORK_ERROR = `${CLI_NAME} encountered a network connectivity error. \ Please check your network connection and try your command again. \ Check on Twilio service status at https://status.twilio.com/`; diff --git a/src/services/messaging/templates.js b/src/services/messaging/templates.js index 00285b71..3a651fea 100644 --- a/src/services/messaging/templates.js +++ b/src/services/messaging/templates.js @@ -1,7 +1,7 @@ const { templatize } = require('./templating'); -const configSaved = templatize`twilio-cli configuration saved to "${'path'}"`; +exports.configSaved = templatize`twilio-cli configuration saved to "${'path'}"`; -module.exports = { - configSaved -}; +exports.unexpectedError = templatize`twilio-cli encountered an unexpected error. \ +To report this issue, execute the command with the "-l debug" flag, then copy the output to a new issue here: \ +"${'url'}"`; diff --git a/src/services/require-install.js b/src/services/require-install.js index f7b72b21..59c093ac 100644 --- a/src/services/require-install.js +++ b/src/services/require-install.js @@ -8,7 +8,7 @@ const { logger } = require('./messaging/logging'); * Retrieves the plugin for a given command. */ const getCommandPlugin = command => { - for (let plugin of command.config.plugins) { + for (let plugin of command.config.plugins || []) { for (let pluginCommand of plugin.commands) { if (pluginCommand.id === command.id || pluginCommand.aliases.includes(command.id)) { // Check the plugin options/config name first. This will contain the diff --git a/test/base-commands/base-command.test.js b/test/base-commands/base-command.test.js index b4318e7f..cc8d4745 100644 --- a/test/base-commands/base-command.test.js +++ b/test/base-commands/base-command.test.js @@ -67,6 +67,32 @@ describe('base-commands', () => { await expect(ctx.testCmd.catch(new TwilioCliError('hey-o!'))).to.be.rejectedWith(TwilioCliError); }); + describe('getIssueUrl', () => { + baseCommandTest.it('follows the proper precedence order', ctx => { + const pjson = { + bugs: 'could be', + homepage: 'maybe', + repository: 'nope' + }; + + expect(ctx.testCmd.getIssueUrl({ pjson })).to.equal('could be'); + + delete pjson.bugs; + expect(ctx.testCmd.getIssueUrl({ pjson })).to.equal('maybe'); + + delete pjson.homepage; + expect(ctx.testCmd.getIssueUrl({ pjson })).to.equal('nope'); + }); + + baseCommandTest.it('handles url properties', ctx => { + expect(ctx.testCmd.getIssueUrl({ pjson: { bugs: { email: 'me', url: 'you' } } })).to.equal('you'); + }); + + baseCommandTest.it('use the main repo when no url is found', ctx => { + expect(ctx.testCmd.getIssueUrl({ pjson: { anything: 'nothing' } })).to.equal('https://github.com/twilio/twilio-cli/issues'); + }); + }); + describe('sanitizeDateString', () => { baseCommandTest.it('check date is sliced correctly', ctx => { expect(ctx.testCmd.sanitizeDateString('Fri May 24 2019 11:43:11 GMT-0600 (MDT)')).to.equal('May 24 2019 11:43:11 GMT-0600');