From f8957cb01bc11982a0cf079c3d21b3eb0a257235 Mon Sep 17 00:00:00 2001 From: Camden Phalen Date: Mon, 16 Oct 2023 14:05:04 -0400 Subject: [PATCH 1/7] Add errorHandler files --- packages/cli/lib/errorHandlers/apiErrors.js | 343 ++++++++++++++++++ .../cli/lib/errorHandlers/fileSystemErrors.js | 50 +++ .../cli/lib/errorHandlers/standardErrors.js | 86 +++++ 3 files changed, 479 insertions(+) create mode 100644 packages/cli/lib/errorHandlers/apiErrors.js create mode 100644 packages/cli/lib/errorHandlers/fileSystemErrors.js create mode 100644 packages/cli/lib/errorHandlers/standardErrors.js diff --git a/packages/cli/lib/errorHandlers/apiErrors.js b/packages/cli/lib/errorHandlers/apiErrors.js new file mode 100644 index 000000000..8c68a2adb --- /dev/null +++ b/packages/cli/lib/errorHandlers/apiErrors.js @@ -0,0 +1,343 @@ +const { logger } = require('@hubspot/cli-lib/logger'); +const { getAccountConfig } = require('@hubspot/cli-lib/lib/config'); +const { + SCOPE_GROUPS, + PERSONAL_ACCESS_KEY_AUTH_METHOD, +} = require('@hubspot/cli-lib/lib/constants'); +const { + fetchScopeData, +} = require('@hubspot/cli-lib/api/localDevAuth/authenticated'); +const { + debugErrorAndContext, + logErrorInstance, + ErrorContext, +} = require('./standardErrors'); + +const isApiStatusCodeError = err => + err.name === 'StatusCodeError' || + (err.statusCode >= 100 && err.statusCode < 600); + +const isApiUploadValidationError = err => + !!( + err.statusCode === 400 && + err.response && + err.response.body && + (err.response.body.message || err.response.body.errors) + ); + +const isMissingScopeError = err => + err.name === 'StatusCodeError' && + err.statusCode === 403 && + err.error && + err.error.category === 'MISSING_SCOPES'; + +const isGatingError = err => + isSpecifiedError(err, { statusCode: 403, category: 'GATED' }); + +const isSpecifiedError = (err, { statusCode, category, subCategory } = {}) => { + const statusCodeErr = !statusCode || err.statusCode === statusCode; + const categoryErr = + !category || (err.error && err.error.category === category); + const subCategoryErr = + !subCategory || (err.error && err.error.subCategory === subCategory); + + return ( + err.name === 'StatusCodeError' && + statusCodeErr && + categoryErr && + subCategoryErr + ); +}; + +const isSpecifiedHubSpotAuthError = ( + err, + { statusCode, category, subCategory } +) => { + const statusCodeErr = !statusCode || err.statusCode === statusCode; + const categoryErr = !category || err.category === category; + const subCategoryErr = !subCategory || err.subCategory === subCategory; + return ( + err.name === 'HubSpotAuthError' && + statusCodeErr && + categoryErr && + subCategoryErr + ); +}; + +const contactSupportString = + 'Please try again or visit https://help.hubspot.com/ to submit a ticket or contact HubSpot Support if the issue persists.'; + +const parseValidationErrors = (responseBody = {}) => { + const errorMessages = []; + + const { errors, message } = responseBody; + + if (message) { + errorMessages.push(message); + } + + if (errors) { + const specificErrors = errors.map(error => { + let errorMessage = error.message; + if (error.errorTokens && error.errorTokens.line) { + errorMessage = `line ${error.errorTokens.line}: ${errorMessage}`; + } + return errorMessage; + }); + errorMessages.push(...specificErrors); + } + + return errorMessages; +}; + +class ApiErrorContext extends ErrorContext { + constructor(props = {}) { + super(props); + /** @type {string} */ + this.request = props.request || ''; + /** @type {string} */ + this.payload = props.payload || ''; + /** @type {string} */ + this.projectName = props.projectName || ''; + } +} + +/** + * @param {Error} error + * @param {ApiErrorContext} context + */ +function logValidationErrors(error, context) { + const { response = {} } = error; + const validationErrors = parseValidationErrors(response.body); + if (validationErrors.length) { + validationErrors.forEach(err => { + logger.error(err); + }); + } + debugErrorAndContext(error, context); +} + +/** + * Message segments for API messages. + * + * @enum {string} + */ +const ApiMethodVerbs = { + DEFAULT: 'request', + DELETE: 'delete', + GET: 'request', + PATCH: 'update', + POST: 'post', + PUT: 'update', +}; + +/** + * Message segments for API messages. + * + * @enum {string} + */ +const ApiMethodPrepositions = { + DEFAULT: 'for', + DELETE: 'of', + GET: 'for', + PATCH: 'to', + POST: 'to', + PUT: 'to', +}; + +/** + * Logs messages for an error instance resulting from API interaction. + * + * @param {StatusCodeError} error + * @param {ApiErrorContext} context + */ +function logApiStatusCodeError(error, context) { + const { statusCode } = error; + const { method } = error.options || {}; + const { projectName } = context; + const isPutOrPost = method === 'PUT' || method === 'POST'; + const action = ApiMethodVerbs[method] || ApiMethodVerbs.DEFAULT; + const preposition = + ApiMethodPrepositions[method] || ApiMethodPrepositions.DEFAULT; + let messageDetail = ''; + { + const request = context.request + ? `${action} ${preposition} "${context.request}"` + : action; + messageDetail = `${request} in account ${context.accountId}`; + } + const errorMessage = []; + if (isPutOrPost && context.payload) { + errorMessage.push(`Unable to upload "${context.payload}".`); + } + const isProjectMissingScopeError = isMissingScopeError(error) && projectName; + const isProjectGatingError = isGatingError(error) && projectName; + switch (statusCode) { + case 400: + errorMessage.push(`The ${messageDetail} was bad.`); + break; + case 401: + errorMessage.push(`The ${messageDetail} was unauthorized.`); + break; + case 403: + if (isProjectMissingScopeError) { + errorMessage.push( + `Couldn't run the project command because there are scopes missing in your production account. To update scopes, deactivate your current personal access key for ${context.accountId}, and generate a new one. Then run \`hs auth\` to update the CLI with the new key.` + ); + } else if (isProjectGatingError) { + errorMessage.push( + `The current target account ${context.accountId} does not have access to HubSpot projects. To opt in to the CRM Development Beta and use projects, visit https://app.hubspot.com/l/whats-new/betas?productUpdateId=13860216.` + ); + } else { + errorMessage.push(`The ${messageDetail} was forbidden.`); + } + break; + case 404: + if (context.request) { + errorMessage.push( + `The ${action} failed because "${context.request}" was not found in account ${context.accountId}.` + ); + } else { + errorMessage.push(`The ${messageDetail} was not found.`); + } + break; + case 429: + errorMessage.push( + `The ${messageDetail} surpassed the rate limit. Retry in one minute.` + ); + break; + case 503: + errorMessage.push( + `The ${messageDetail} could not be handled at this time. ${contactSupportString}` + ); + break; + default: + if (statusCode >= 500 && statusCode < 600) { + errorMessage.push( + `The ${messageDetail} failed due to a server error. ${contactSupportString}` + ); + } else if (statusCode >= 400 && statusCode < 500) { + errorMessage.push(`The ${messageDetail} failed due to a client error.`); + } else { + errorMessage.push(`The ${messageDetail} failed.`); + } + break; + } + if ( + error.error && + error.error.message && + !isProjectMissingScopeError && + !isProjectGatingError + ) { + errorMessage.push(error.error.message); + } + if (error.error && error.error.errors) { + error.error.errors.forEach(err => { + errorMessage.push('\n- ' + err.message); + }); + } + logger.error(errorMessage.join(' ')); + debugErrorAndContext(error, context); +} + +/** + * Logs a message for an error instance resulting from API interaction. + * + * @param {Error|SystemError|Object} error + * @param {ApiErrorContext} context + */ +function logApiErrorInstance(error, context) { + // StatusCodeError + if (isApiStatusCodeError(error)) { + logApiStatusCodeError(error, context); + return; + } + logErrorInstance(error, context); +} + +/** + * Logs a message for an error instance resulting from filemapper API upload. + * + * @param {Error|SystemError|Object} error + * @param {ApiErrorContext} context + */ +function logApiUploadErrorInstance(error, context) { + if (isApiUploadValidationError(error)) { + logValidationErrors(error, context); + return; + } + logApiErrorInstance(error, context); +} + +async function verifyAccessKeyAndUserAccess(accountId, scopeGroup) { + const accountConfig = getAccountConfig(accountId); + const { authType } = accountConfig; + if (authType !== PERSONAL_ACCESS_KEY_AUTH_METHOD.value) { + return; + } + + let scopesData; + try { + scopesData = await fetchScopeData(accountId, scopeGroup); + } catch (e) { + logger.debug(`Error verifying access of scopeGroup ${scopeGroup}: ${e}`); + return; + } + const { portalScopesInGroup, userScopesInGroup } = scopesData; + + if (!portalScopesInGroup.length) { + logger.error( + 'Your account does not have access to this action. Talk to an account admin to request it.' + ); + return; + } + + if (!portalScopesInGroup.every(s => userScopesInGroup.includes(s))) { + logger.error( + "You don't have access to this action. Ask an account admin to change your permissions in Users & Teams settings." + ); + return; + } else { + logger.error( + 'Your access key does not allow this action. Please generate a new access key by running "hs auth personalaccesskey".' + ); + return; + } +} + +/** + * Logs a message for an error instance resulting from API interaction + * related to serverless function. + * + * @param {int} accountId + * @param {Error|SystemError|Object} error + * @param {ApiErrorContext} context + */ +async function logServerlessFunctionApiErrorInstance( + accountId, + error, + context +) { + if (isMissingScopeError(error)) { + await verifyAccessKeyAndUserAccess(accountId, SCOPE_GROUPS.functions); + return; + } + + // StatusCodeError + if (isApiStatusCodeError(error)) { + logApiStatusCodeError(error, context); + return; + } + logErrorInstance(error, context); +} + +module.exports = { + ApiErrorContext, + parseValidationErrors, + logApiErrorInstance, + logApiUploadErrorInstance, + logServerlessFunctionApiErrorInstance, + isMissingScopeError, + isSpecifiedError, + isSpecifiedHubSpotAuthError, +}; diff --git a/packages/cli/lib/errorHandlers/fileSystemErrors.js b/packages/cli/lib/errorHandlers/fileSystemErrors.js new file mode 100644 index 000000000..d7d144887 --- /dev/null +++ b/packages/cli/lib/errorHandlers/fileSystemErrors.js @@ -0,0 +1,50 @@ +const { logger } = require('@hubspot/cli-lib/logger'); +const { + ErrorContext, + isSystemError, + debugErrorAndContext, +} = require('./standardErrors'); + +class FileSystemErrorContext extends ErrorContext { + constructor(props = {}) { + super(props); + /** @type {string} */ + this.filepath = props.filepath || ''; + /** @type {boolean} */ + this.read = !!props.read; + /** @type {boolean} */ + this.write = !!props.write; + } +} + +/** + * Logs a message for an error instance resulting from filesystem interaction. + * + * @param {Error|SystemError|Object} error + * @param {FileSystemErrorContext} context + */ +function logFileSystemErrorInstance(error, context) { + let fileAction = ''; + if (context.read) { + fileAction = 'reading from'; + } else if (context.write) { + fileAction = 'writing to'; + } else { + fileAction = 'accessing'; + } + const filepath = context.filepath + ? `"${context.filepath}"` + : 'a file or folder'; + const message = [`An error occurred while ${fileAction} ${filepath}.`]; + // Many `fs` errors will be `SystemError`s + if (isSystemError(error)) { + message.push(`This is the result of a system error: ${error.message}`); + } + logger.error(message.join(' ')); + debugErrorAndContext(error, context); +} + +module.exports = { + FileSystemErrorContext, + logFileSystemErrorInstance, +}; diff --git a/packages/cli/lib/errorHandlers/standardErrors.js b/packages/cli/lib/errorHandlers/standardErrors.js new file mode 100644 index 000000000..9f36338a8 --- /dev/null +++ b/packages/cli/lib/errorHandlers/standardErrors.js @@ -0,0 +1,86 @@ +const { HubSpotAuthError } = require('@hubspot/cli-lib/lib/models/Errors'); +const { logger } = require('@hubspot/cli-lib/logger'); + +const isSystemError = err => + err.errno != null && err.code != null && err.syscall != null; +const isFatalError = err => err instanceof HubSpotAuthError; + +// TODO: Make these TS interfaces +class ErrorContext { + constructor(props = {}) { + /** @type {number} */ + this.accountId = props.accountId; + } +} + +/** + * Logs (debug) the error and context objects. + * + * @param {SystemError} error + * @param {ErrorContext} context + */ +function debugErrorAndContext(error, context) { + if (error.name === 'StatusCodeError') { + const { statusCode, message, response } = error; + logger.debug('Error: %o', { + statusCode, + message, + url: response.request.href, + method: response.request.method, + response: response.body, + headers: response.headers, + }); + } else { + logger.debug('Error: %o', error); + } + logger.debug('Context: %o', context); +} + +/** + * Logs a SystemError + * @see {@link https://nodejs.org/api/errors.html#errors_class_systemerror} + * + * @param {SystemError} error + * @param {ErrorContext} context + */ +function logSystemError(error, context) { + logger.error(`A system error has occurred: ${error.message}`); + debugErrorAndContext(error, context); +} + +/** + * Logs a message for an error instance of type not asserted. + * + * @param {Error|SystemError|Object} error + * @param {ErrorContext} context + */ +function logErrorInstance(error, context) { + // SystemError + if (isSystemError(error)) { + logSystemError(error, context); + return; + } + if (error instanceof Error || error.message || error.reason) { + // Error or Error subclass + const name = error.name || 'Error'; + const message = [`A ${name} has occurred.`]; + [error.message, error.reason].forEach(msg => { + if (msg) { + message.push(msg); + } + }); + logger.error(message.join(' ')); + } else { + // Unknown errors + logger.error(`An unknown error has occurred.`); + } + debugErrorAndContext(error, context); +} + +module.exports = { + debugErrorAndContext, + ErrorContext, + isFatalError, + isSystemError, + logErrorInstance, +}; From 2cc9160acdd1eadc116f3fdcdf45447c3566b1a6 Mon Sep 17 00:00:00 2001 From: Camden Phalen Date: Mon, 16 Oct 2023 16:06:52 -0400 Subject: [PATCH 2/7] replace references to cli-lib/errorHandlers --- packages/cli/bin/cli.js | 2 +- packages/cli/commands/accounts/clean.js | 2 +- packages/cli/commands/create.js | 2 +- packages/cli/commands/customObject/create.js | 2 +- packages/cli/commands/customObject/schema/create.js | 4 +++- packages/cli/commands/customObject/schema/delete.js | 4 +++- .../cli/commands/customObject/schema/fetch-all.js | 4 +++- packages/cli/commands/customObject/schema/fetch.js | 4 +++- packages/cli/commands/customObject/schema/list.js | 4 +++- packages/cli/commands/customObject/schema/update.js | 4 +++- packages/cli/commands/filemanager/upload.js | 4 ++-- packages/cli/commands/functions/deploy.js | 2 +- packages/cli/commands/functions/list.js | 2 +- packages/cli/commands/hubdb/clear.js | 2 +- packages/cli/commands/hubdb/create.js | 2 +- packages/cli/commands/hubdb/delete.js | 2 +- packages/cli/commands/hubdb/fetch.js | 2 +- packages/cli/commands/init.js | 2 +- packages/cli/commands/lint.js | 2 +- packages/cli/commands/list.js | 2 +- packages/cli/commands/mv.js | 2 +- packages/cli/commands/project/add.js | 2 +- packages/cli/commands/project/deploy.js | 2 +- packages/cli/commands/project/dev.js | 11 +++++------ packages/cli/commands/project/download.js | 2 +- packages/cli/commands/project/listBuilds.js | 2 +- packages/cli/commands/project/logs.js | 2 +- packages/cli/commands/project/upload.js | 6 ++---- packages/cli/commands/project/watch.js | 2 +- packages/cli/commands/remove.js | 2 +- packages/cli/commands/sandbox/create.js | 6 ++---- packages/cli/commands/sandbox/delete.js | 13 +++++++------ packages/cli/commands/sandbox/sync.js | 8 ++------ packages/cli/commands/secrets/addSecret.js | 2 +- packages/cli/commands/secrets/deleteSecret.js | 2 +- packages/cli/commands/secrets/listSecrets.js | 2 +- packages/cli/commands/secrets/updateSecret.js | 2 +- packages/cli/commands/upload.js | 4 ++-- packages/cli/lib/projects.js | 8 +++----- packages/cli/lib/projectsWatch.js | 2 +- packages/cli/lib/prompts/downloadProjectPrompt.js | 2 +- packages/cli/lib/sandbox-create.js | 4 ++-- packages/cli/lib/sandbox-sync.js | 10 +++++----- packages/cli/lib/serverlessLogs.js | 2 +- 44 files changed, 78 insertions(+), 76 deletions(-) diff --git a/packages/cli/bin/cli.js b/packages/cli/bin/cli.js index 1dab8adfe..430d7edeb 100755 --- a/packages/cli/bin/cli.js +++ b/packages/cli/bin/cli.js @@ -5,7 +5,7 @@ const updateNotifier = require('update-notifier'); const chalk = require('chalk'); const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../lib/errorHandlers/standardErrors'); const { setLogLevel, getCommandName } = require('../lib/commonOpts'); const { trackHelpUsage, diff --git a/packages/cli/commands/accounts/clean.js b/packages/cli/commands/accounts/clean.js index d087d8f40..2a330370c 100644 --- a/packages/cli/commands/accounts/clean.js +++ b/packages/cli/commands/accounts/clean.js @@ -21,7 +21,7 @@ const SpinniesManager = require('../../lib/SpinniesManager'); const { deleteAccount } = require('@hubspot/cli-lib/lib/config'); const { isSpecifiedHubSpotAuthError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); +} = require('../../lib/errorHandlers/apiErrors'); const i18nKey = 'cli.commands.accounts.subcommands.clean'; diff --git a/packages/cli/commands/create.js b/packages/cli/commands/create.js index 45550e09d..a8eae7038 100644 --- a/packages/cli/commands/create.js +++ b/packages/cli/commands/create.js @@ -24,7 +24,7 @@ const fs = require('fs-extra'); const { logFileSystemErrorInstance, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../lib/errorHandlers/fileSystemErrors'); const { logger } = require('@hubspot/cli-lib/logger'); const { setLogLevel, getAccountId } = require('../lib/commonOpts'); const { logDebugInfo } = require('../lib/debugInfo'); diff --git a/packages/cli/commands/customObject/create.js b/packages/cli/commands/customObject/create.js index 1f4df5d62..2212f92bd 100644 --- a/packages/cli/commands/customObject/create.js +++ b/packages/cli/commands/customObject/create.js @@ -1,5 +1,5 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const { getAbsoluteFilePath } = require('@hubspot/cli-lib/path'); const { isFileValidJSON, diff --git a/packages/cli/commands/customObject/schema/create.js b/packages/cli/commands/customObject/schema/create.js index 488adf6ca..83c505eb5 100644 --- a/packages/cli/commands/customObject/schema/create.js +++ b/packages/cli/commands/customObject/schema/create.js @@ -1,5 +1,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { + logErrorInstance, +} = require('../../../lib/errorHandlers/standardErrors'); const { getAbsoluteFilePath } = require('@hubspot/cli-lib/path'); const { isFileValidJSON, diff --git a/packages/cli/commands/customObject/schema/delete.js b/packages/cli/commands/customObject/schema/delete.js index d466173af..393c8efaa 100644 --- a/packages/cli/commands/customObject/schema/delete.js +++ b/packages/cli/commands/customObject/schema/delete.js @@ -1,5 +1,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { + logErrorInstance, +} = require('../../../lib/errorHandlers/standardErrors'); const { loadAndValidateOptions } = require('../../../lib/validation'); const { trackCommandUsage } = require('../../../lib/usageTracking'); diff --git a/packages/cli/commands/customObject/schema/fetch-all.js b/packages/cli/commands/customObject/schema/fetch-all.js index 379b759ea..b2ba14735 100644 --- a/packages/cli/commands/customObject/schema/fetch-all.js +++ b/packages/cli/commands/customObject/schema/fetch-all.js @@ -1,5 +1,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { + logErrorInstance, +} = require('../../../lib/errorHandlers/standardErrors'); const { loadAndValidateOptions } = require('../../../lib/validation'); const { trackCommandUsage } = require('../../../lib/usageTracking'); diff --git a/packages/cli/commands/customObject/schema/fetch.js b/packages/cli/commands/customObject/schema/fetch.js index 90287a15a..431587ae4 100644 --- a/packages/cli/commands/customObject/schema/fetch.js +++ b/packages/cli/commands/customObject/schema/fetch.js @@ -1,7 +1,9 @@ const path = require('path'); const { isConfigFlagEnabled } = require('@hubspot/cli-lib'); const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { + logErrorInstance, +} = require('../../../lib/errorHandlers/standardErrors'); const { ConfigFlags } = require('@hubspot/cli-lib/lib/constants'); const { downloadSchema, getResolvedPath } = require('@hubspot/cli-lib/schema'); const { fetchSchema } = require('@hubspot/cli-lib/api/fileTransport'); diff --git a/packages/cli/commands/customObject/schema/list.js b/packages/cli/commands/customObject/schema/list.js index 1bd6c8ffe..65ec3dce6 100644 --- a/packages/cli/commands/customObject/schema/list.js +++ b/packages/cli/commands/customObject/schema/list.js @@ -1,5 +1,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { + logErrorInstance, +} = require('../../../lib/errorHandlers/standardErrors'); const { loadAndValidateOptions } = require('../../../lib/validation'); const { trackCommandUsage } = require('../../../lib/usageTracking'); diff --git a/packages/cli/commands/customObject/schema/update.js b/packages/cli/commands/customObject/schema/update.js index 512642a20..8608826f9 100644 --- a/packages/cli/commands/customObject/schema/update.js +++ b/packages/cli/commands/customObject/schema/update.js @@ -1,5 +1,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { + logErrorInstance, +} = require('../../../lib/errorHandlers/standardErrors'); const { getAbsoluteFilePath } = require('@hubspot/cli-lib/path'); const { isFileValidJSON, diff --git a/packages/cli/commands/filemanager/upload.js b/packages/cli/commands/filemanager/upload.js index f48ebcf29..cd0ac8987 100644 --- a/packages/cli/commands/filemanager/upload.js +++ b/packages/cli/commands/filemanager/upload.js @@ -6,10 +6,10 @@ const { uploadFile } = require('@hubspot/cli-lib/api/fileManager'); const { getCwd, convertToUnixPath } = require('@hubspot/cli-lib/path'); const { logger } = require('@hubspot/cli-lib/logger'); const { - logErrorInstance, ApiErrorContext, logApiUploadErrorInstance, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const { validateSrcAndDestPaths } = require('@hubspot/cli-lib/modules'); const { shouldIgnoreFile } = require('@hubspot/cli-lib/ignoreRules'); diff --git a/packages/cli/commands/functions/deploy.js b/packages/cli/commands/functions/deploy.js index 5b187bdd6..ed5e94eda 100644 --- a/packages/cli/commands/functions/deploy.js +++ b/packages/cli/commands/functions/deploy.js @@ -9,7 +9,7 @@ const { trackCommandUsage } = require('../../lib/usageTracking'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { POLLING_DELAY } = require('@hubspot/cli-lib/lib/constants'); const { logger } = require('@hubspot/cli-lib/logger'); const { diff --git a/packages/cli/commands/functions/list.js b/packages/cli/commands/functions/list.js index 5d8e7e89f..83bf607b1 100644 --- a/packages/cli/commands/functions/list.js +++ b/packages/cli/commands/functions/list.js @@ -3,7 +3,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { getFunctionArrays } = require('../../lib/getFunctionArrays'); const { getTableContents, diff --git a/packages/cli/commands/hubdb/clear.js b/packages/cli/commands/hubdb/clear.js index 978fe4cdf..37fa86b13 100644 --- a/packages/cli/commands/hubdb/clear.js +++ b/packages/cli/commands/hubdb/clear.js @@ -1,5 +1,5 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const { clearHubDbTableRows } = require('@hubspot/cli-lib/hubdb'); const { publishTable } = require('@hubspot/cli-lib/api/hubdb'); diff --git a/packages/cli/commands/hubdb/create.js b/packages/cli/commands/hubdb/create.js index e81fa2350..24d35f2de 100644 --- a/packages/cli/commands/hubdb/create.js +++ b/packages/cli/commands/hubdb/create.js @@ -1,7 +1,7 @@ const path = require('path'); const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const { getCwd } = require('@hubspot/cli-lib/path'); const { createHubDbTable } = require('@hubspot/cli-lib/hubdb'); diff --git a/packages/cli/commands/hubdb/delete.js b/packages/cli/commands/hubdb/delete.js index e4505feaa..a1998bde0 100644 --- a/packages/cli/commands/hubdb/delete.js +++ b/packages/cli/commands/hubdb/delete.js @@ -1,5 +1,5 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const { deleteTable } = require('@hubspot/cli-lib/api/hubdb'); const { loadAndValidateOptions } = require('../../lib/validation'); const { trackCommandUsage } = require('../../lib/usageTracking'); diff --git a/packages/cli/commands/hubdb/fetch.js b/packages/cli/commands/hubdb/fetch.js index fc39dcb69..2874681f4 100644 --- a/packages/cli/commands/hubdb/fetch.js +++ b/packages/cli/commands/hubdb/fetch.js @@ -1,5 +1,5 @@ const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const { downloadHubDbTable } = require('@hubspot/cli-lib/hubdb'); const { loadAndValidateOptions } = require('../../lib/validation'); diff --git a/packages/cli/commands/init.js b/packages/cli/commands/init.js index e3fb96121..5fac1061e 100644 --- a/packages/cli/commands/init.js +++ b/packages/cli/commands/init.js @@ -9,7 +9,7 @@ const { const { addConfigOptions } = require('../lib/commonOpts'); const { handleExit } = require('../lib/process'); const { checkAndUpdateGitignore } = require('@hubspot/cli-lib/lib/git'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../lib/errorHandlers/standardErrors'); const { DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME, PERSONAL_ACCESS_KEY_AUTH_METHOD, diff --git a/packages/cli/commands/lint.js b/packages/cli/commands/lint.js index 42d158ddc..7afeaeba4 100644 --- a/packages/cli/commands/lint.js +++ b/packages/cli/commands/lint.js @@ -1,7 +1,7 @@ const { lint } = require('@hubspot/cli-lib/validate'); const { printHublValidationResult } = require('../lib/hublValidate'); const { logger } = require('@hubspot/cli-lib/logger'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../lib/errorHandlers/standardErrors'); const { addConfigOptions, diff --git a/packages/cli/commands/list.js b/packages/cli/commands/list.js index ab8c944ba..9e53ac84c 100644 --- a/packages/cli/commands/list.js +++ b/packages/cli/commands/list.js @@ -12,7 +12,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../lib/errorHandlers/apiErrors'); const { getDirectoryContentsByPath, } = require('@hubspot/cli-lib/api/fileMapper'); diff --git a/packages/cli/commands/mv.js b/packages/cli/commands/mv.js index 5e1ee5344..fc8230e93 100644 --- a/packages/cli/commands/mv.js +++ b/packages/cli/commands/mv.js @@ -3,7 +3,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../lib/errorHandlers/apiErrors'); const { addConfigOptions, diff --git a/packages/cli/commands/project/add.js b/packages/cli/commands/project/add.js index afaefd43a..43c6bc4fe 100644 --- a/packages/cli/commands/project/add.js +++ b/packages/cli/commands/project/add.js @@ -1,6 +1,6 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { getAccountId } = require('@hubspot/cli-lib/lib/config'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const { fetchReleaseData } = require('@hubspot/cli-lib/github'); const { trackCommandUsage } = require('../../lib/usageTracking'); diff --git a/packages/cli/commands/project/deploy.js b/packages/cli/commands/project/deploy.js index 803a2e74d..a785d031e 100644 --- a/packages/cli/commands/project/deploy.js +++ b/packages/cli/commands/project/deploy.js @@ -9,7 +9,7 @@ const { trackCommandUsage } = require('../../lib/usageTracking'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { logger } = require('@hubspot/cli-lib/logger'); const { deployProject, fetchProject } = require('@hubspot/cli-lib/api/dfs'); const { loadAndValidateOptions } = require('../../lib/validation'); diff --git a/packages/cli/commands/project/dev.js b/packages/cli/commands/project/dev.js index 6bdc72f0a..3bbe57e02 100644 --- a/packages/cli/commands/project/dev.js +++ b/packages/cli/commands/project/dev.js @@ -50,18 +50,17 @@ const { PROJECT_DEPLOY_TEXT, ERROR_TYPES, } = require('@hubspot/cli-lib/lib/constants'); -const { - logErrorInstance, - logApiErrorInstance, - ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); + const { buildSandbox } = require('../../lib/sandbox-create'); const { syncSandbox } = require('../../lib/sandbox-sync'); const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls'); const { + logApiErrorInstance, + ApiErrorContext, isMissingScopeError, isSpecifiedError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); +} = require('../../lib/errorHandlers/apiErrors'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const i18nKey = 'cli.commands.project.subcommands.dev'; diff --git a/packages/cli/commands/project/download.js b/packages/cli/commands/project/download.js index bffc08e03..b768d5aea 100644 --- a/packages/cli/commands/project/download.js +++ b/packages/cli/commands/project/download.js @@ -10,7 +10,7 @@ const { getCwd } = require('@hubspot/cli-lib/path'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { logger } = require('@hubspot/cli-lib/logger'); const { extractZipArchive } = require('@hubspot/cli-lib/archive'); const { diff --git a/packages/cli/commands/project/listBuilds.js b/packages/cli/commands/project/listBuilds.js index dbeb4e9b6..0d6627653 100644 --- a/packages/cli/commands/project/listBuilds.js +++ b/packages/cli/commands/project/listBuilds.js @@ -11,7 +11,7 @@ const { i18n } = require('../../lib/lang'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { logger } = require('@hubspot/cli-lib/logger'); const { fetchProject, diff --git a/packages/cli/commands/project/logs.js b/packages/cli/commands/project/logs.js index 3ec105f59..59099b0e4 100644 --- a/packages/cli/commands/project/logs.js +++ b/packages/cli/commands/project/logs.js @@ -25,7 +25,7 @@ const { // const { // logApiErrorInstance, // ApiErrorContext, -// } = require('@hubspot/cli-lib/errorHandlers'); +// } = require('../../lib/errorHandlers/apiErrors'); // const { // getFunctionLogs, // getLatestFunctionLog, diff --git a/packages/cli/commands/project/upload.js b/packages/cli/commands/project/upload.js index b52dfcb14..7973218c4 100644 --- a/packages/cli/commands/project/upload.js +++ b/packages/cli/commands/project/upload.js @@ -21,13 +21,11 @@ const { const { i18n } = require('../../lib/lang'); const { getAccountConfig } = require('@hubspot/cli-lib'); const { ERROR_TYPES } = require('@hubspot/cli-lib/lib/constants'); -const { - isSpecifiedError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); + isSpecifiedError, +} = require('../../lib/errorHandlers/apiErrors'); const { EXIT_CODES } = require('../../lib/enums/exitCodes'); const i18nKey = 'cli.commands.project.subcommands.upload'; diff --git a/packages/cli/commands/project/watch.js b/packages/cli/commands/project/watch.js index 7de81a830..00f9d08cd 100644 --- a/packages/cli/commands/project/watch.js +++ b/packages/cli/commands/project/watch.js @@ -3,7 +3,7 @@ const { createWatcher } = require('../../lib/projectsWatch'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { logger } = require('@hubspot/cli-lib/logger'); const { ERROR_TYPES } = require('@hubspot/cli-lib/lib/constants'); const { diff --git a/packages/cli/commands/remove.js b/packages/cli/commands/remove.js index 7531380ae..ba6064bad 100644 --- a/packages/cli/commands/remove.js +++ b/packages/cli/commands/remove.js @@ -3,7 +3,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../lib/errorHandlers/apiErrors'); const { addConfigOptions, diff --git a/packages/cli/commands/sandbox/create.js b/packages/cli/commands/sandbox/create.js index ca5a691da..7ba0bf1cc 100644 --- a/packages/cli/commands/sandbox/create.js +++ b/packages/cli/commands/sandbox/create.js @@ -32,10 +32,8 @@ const { } = require('../../lib/prompts/sandboxesPrompt'); const { promptUser } = require('../../lib/prompts/promptUtils'); const { syncSandbox } = require('../../lib/sandbox-sync'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); -const { - isMissingScopeError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); +const { isMissingScopeError } = require('../../lib/errorHandlers/apiErrors'); const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls'); const i18nKey = 'cli.commands.sandbox.subcommands.create'; diff --git a/packages/cli/commands/sandbox/delete.js b/packages/cli/commands/sandbox/delete.js index d275f0da7..a447ef234 100644 --- a/packages/cli/commands/sandbox/delete.js +++ b/packages/cli/commands/sandbox/delete.js @@ -9,9 +9,13 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { trackCommandUsage } = require('../../lib/usageTracking'); const { loadAndValidateOptions } = require('../../lib/validation'); const { + logErrorInstance, debugErrorAndContext, -} = require('@hubspot/cli-lib/errorHandlers/standardErrors'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/standardErrors'); +const { + isSpecifiedError, + isSpecifiedHubSpotAuthError, +} = require('../../lib/errorHandlers/apiErrors'); const { deleteSandbox } = require('@hubspot/cli-lib/sandboxes'); const { i18n } = require('../../lib/lang'); const { getConfig, getEnv, getAccountConfig } = require('@hubspot/cli-lib'); @@ -26,10 +30,7 @@ const { const { EXIT_CODES } = require('../../lib/enums/exitCodes'); const { promptUser } = require('../../lib/prompts/promptUtils'); const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls'); -const { - isSpecifiedError, - isSpecifiedHubSpotAuthError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); + const { getAccountName } = require('../../lib/sandboxes'); const { getValidEnv } = require('@hubspot/cli-lib/lib/environment'); diff --git a/packages/cli/commands/sandbox/sync.js b/packages/cli/commands/sandbox/sync.js index 13d730b91..3b6a3a826 100644 --- a/packages/cli/commands/sandbox/sync.js +++ b/packages/cli/commands/sandbox/sync.js @@ -24,12 +24,8 @@ const { } = require('../../lib/sandboxes'); const { syncSandbox } = require('../../lib/sandbox-sync'); const { getValidEnv } = require('@hubspot/cli-lib/lib/environment'); -const { - isSpecifiedError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); -const { - logErrorInstance, -} = require('@hubspot/cli-lib/errorHandlers/standardErrors'); +const { isSpecifiedError } = require('../../lib/errorHandlers/apiErrors'); +const { logErrorInstance } = require('../../lib/errorHandlers/standardErrors'); const i18nKey = 'cli.commands.sandbox.subcommands.sync'; diff --git a/packages/cli/commands/secrets/addSecret.js b/packages/cli/commands/secrets/addSecret.js index 7c10705e8..c4a55a2da 100644 --- a/packages/cli/commands/secrets/addSecret.js +++ b/packages/cli/commands/secrets/addSecret.js @@ -2,7 +2,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { logServerlessFunctionApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { addSecret } = require('@hubspot/cli-lib/api/secrets'); const { loadAndValidateOptions } = require('../../lib/validation'); diff --git a/packages/cli/commands/secrets/deleteSecret.js b/packages/cli/commands/secrets/deleteSecret.js index 997005996..c6030797b 100644 --- a/packages/cli/commands/secrets/deleteSecret.js +++ b/packages/cli/commands/secrets/deleteSecret.js @@ -2,7 +2,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { logServerlessFunctionApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { deleteSecret } = require('@hubspot/cli-lib/api/secrets'); const { loadAndValidateOptions } = require('../../lib/validation'); diff --git a/packages/cli/commands/secrets/listSecrets.js b/packages/cli/commands/secrets/listSecrets.js index 9061add27..68440ef67 100644 --- a/packages/cli/commands/secrets/listSecrets.js +++ b/packages/cli/commands/secrets/listSecrets.js @@ -2,7 +2,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { logServerlessFunctionApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { fetchSecrets } = require('@hubspot/cli-lib/api/secrets'); const { loadAndValidateOptions } = require('../../lib/validation'); diff --git a/packages/cli/commands/secrets/updateSecret.js b/packages/cli/commands/secrets/updateSecret.js index 9526115f0..a48372a00 100644 --- a/packages/cli/commands/secrets/updateSecret.js +++ b/packages/cli/commands/secrets/updateSecret.js @@ -2,7 +2,7 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { logServerlessFunctionApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { updateSecret } = require('@hubspot/cli-lib/api/secrets'); const { loadAndValidateOptions } = require('../../lib/validation'); diff --git a/packages/cli/commands/upload.js b/packages/cli/commands/upload.js index 6f70f6cfa..f24aa3131 100644 --- a/packages/cli/commands/upload.js +++ b/packages/cli/commands/upload.js @@ -10,10 +10,10 @@ const { } = require('@hubspot/cli-lib/path'); const { logger } = require('@hubspot/cli-lib/logger'); const { - logErrorInstance, ApiErrorContext, logApiUploadErrorInstance, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../lib/errorHandlers/apiErrors'); +const { logErrorInstance } = require('../lib/errorHandlers/standardErrors'); const { validateSrcAndDestPaths } = require('@hubspot/cli-lib/modules'); const { shouldIgnoreFile } = require('@hubspot/cli-lib/ignoreRules'); diff --git a/packages/cli/lib/projects.js b/packages/cli/lib/projects.js index 83aebf040..1f29746bb 100644 --- a/packages/cli/lib/projects.js +++ b/packages/cli/lib/projects.js @@ -29,10 +29,6 @@ const { fetchProject, uploadProject, } = require('@hubspot/cli-lib/api/dfs'); -const { - logApiErrorInstance, - ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); const { shouldIgnoreFile } = require('@hubspot/cli-lib/ignoreRules'); const { getCwd, getAbsoluteFilePath } = require('@hubspot/cli-lib/path'); const { downloadGitHubRepoContents } = require('@hubspot/cli-lib/github'); @@ -42,9 +38,11 @@ const { uiLine, uiLink, uiAccountDescription } = require('../lib/ui'); const { i18n } = require('./lang'); const SpinniesManager = require('./SpinniesManager'); const { + logApiErrorInstance, + ApiErrorContext, isSpecifiedError, isSpecifiedHubSpotAuthError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); +} = require('./errorHandlers/apiErrors'); const { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH } = require('./constants'); const i18nKey = 'cli.lib.projects'; diff --git a/packages/cli/lib/projectsWatch.js b/packages/cli/lib/projectsWatch.js index 46da8f7a8..0b459642a 100644 --- a/packages/cli/lib/projectsWatch.js +++ b/packages/cli/lib/projectsWatch.js @@ -5,7 +5,7 @@ const { default: PQueue } = require('p-queue'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('./errorHandlers/apiErrors'); const { i18n } = require('@hubspot/cli-lib/lib/lang'); const { logger } = require('@hubspot/cli-lib/logger'); const { isAllowedExtension } = require('@hubspot/cli-lib/path'); diff --git a/packages/cli/lib/prompts/downloadProjectPrompt.js b/packages/cli/lib/prompts/downloadProjectPrompt.js index 45b5b8893..9f3a19990 100644 --- a/packages/cli/lib/prompts/downloadProjectPrompt.js +++ b/packages/cli/lib/prompts/downloadProjectPrompt.js @@ -4,7 +4,7 @@ const { fetchProjects } = require('@hubspot/cli-lib/api/dfs'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { EXIT_CODES } = require('../enums/exitCodes'); const { i18n } = require('../lang'); diff --git a/packages/cli/lib/sandbox-create.js b/packages/cli/lib/sandbox-create.js index 45291aa5f..ffc82c6c4 100644 --- a/packages/cli/lib/sandbox-create.js +++ b/packages/cli/lib/sandbox-create.js @@ -12,11 +12,11 @@ const { logger } = require('@hubspot/cli-lib/logger'); const { debugErrorAndContext, logErrorInstance, -} = require('@hubspot/cli-lib/errorHandlers/standardErrors'); +} = require('./errorHandlers/standardErrors'); const { isMissingScopeError, isSpecifiedError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); +} = require('./errorHandlers/apiErrors'); const { getHubSpotWebsiteOrigin } = require('@hubspot/cli-lib/lib/urls'); const { getEnv, getAccountId } = require('@hubspot/cli-lib'); const { createSandbox } = require('@hubspot/cli-lib/sandboxes'); diff --git a/packages/cli/lib/sandbox-sync.js b/packages/cli/lib/sandbox-sync.js index a0e139fd4..384cda83f 100644 --- a/packages/cli/lib/sandbox-sync.js +++ b/packages/cli/lib/sandbox-sync.js @@ -11,17 +11,17 @@ const { syncTypes, } = require('./sandboxes'); const { initiateSync } = require('@hubspot/cli-lib/sandboxes'); -const { logErrorInstance } = require('@hubspot/cli-lib/errorHandlers'); +const { + debugErrorAndContext, + logErrorInstance, +} = require('./errorHandlers/standardErrors'); const { isSpecifiedError, isMissingScopeError, -} = require('@hubspot/cli-lib/errorHandlers/apiErrors'); +} = require('./errorHandlers/apiErrors'); const { getSandboxTypeAsString } = require('./sandboxes'); const { getAccountId } = require('@hubspot/cli-lib'); const { uiAccountDescription } = require('./ui'); -const { - debugErrorAndContext, -} = require('@hubspot/cli-lib/errorHandlers/standardErrors'); const i18nKey = 'cli.lib.sandbox.sync'; diff --git a/packages/cli/lib/serverlessLogs.js b/packages/cli/lib/serverlessLogs.js index e70c9fffb..8dcd0cbb8 100644 --- a/packages/cli/lib/serverlessLogs.js +++ b/packages/cli/lib/serverlessLogs.js @@ -8,7 +8,7 @@ const { logServerlessFunctionApiErrorInstance, logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('./errorHandlers/apiErrors'); const { base64EncodeString } = require('@hubspot/cli-lib/lib/encoding'); const { EXIT_CODES } = require('../lib/enums/exitCodes'); From edd481818939923ebd065f6045c92802de7c17cf Mon Sep 17 00:00:00 2001 From: Camden Phalen Date: Mon, 16 Oct 2023 16:31:01 -0400 Subject: [PATCH 3/7] Remove cli-lib/errorHandlers from other CLI packages --- .../cli/lib/prompts/projectsLogsPrompt.js | 2 +- packages/serverless-dev-runtime/lib/server.js | 7 +- .../HubSpotAutoUploadPlugin.js | 66 +++++++++++++++---- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/packages/cli/lib/prompts/projectsLogsPrompt.js b/packages/cli/lib/prompts/projectsLogsPrompt.js index a73ec45bc..d81864c13 100644 --- a/packages/cli/lib/prompts/projectsLogsPrompt.js +++ b/packages/cli/lib/prompts/projectsLogsPrompt.js @@ -6,7 +6,7 @@ const { getProjectConfig, ensureProjectExists } = require('../projects'); const { logApiErrorInstance, ApiErrorContext, -} = require('@hubspot/cli-lib/errorHandlers'); +} = require('../../lib/errorHandlers/apiErrors'); const { logger } = require('@hubspot/cli-lib/logger'); const { EXIT_CODES } = require('../enums/exitCodes'); diff --git a/packages/serverless-dev-runtime/lib/server.js b/packages/serverless-dev-runtime/lib/server.js index e2f79c8cc..36c9a429b 100644 --- a/packages/serverless-dev-runtime/lib/server.js +++ b/packages/serverless-dev-runtime/lib/server.js @@ -3,9 +3,6 @@ const bodyParser = require('body-parser'); const cors = require('cors'); const chalk = require('chalk'); const { logger, setLogLevel, LOG_LEVEL } = require('@hubspot/cli-lib/logger'); -const { - logErrorInstance, -} = require('@hubspot/cli-lib/errorHandlers/standardErrors'); const { getTableContents, getTableHeader, @@ -181,7 +178,9 @@ const startServer = async callback => { }, }; } catch (e) { - logErrorInstance(e, { + logger.error(`A system error has occurred: ${e.message}`); + logger.debug(e); + logger.debug({ port, accountId, functionPath, diff --git a/packages/webpack-cms-plugins/HubSpotAutoUploadPlugin.js b/packages/webpack-cms-plugins/HubSpotAutoUploadPlugin.js index ae27ee163..1afdc4a60 100644 --- a/packages/webpack-cms-plugins/HubSpotAutoUploadPlugin.js +++ b/packages/webpack-cms-plugins/HubSpotAutoUploadPlugin.js @@ -5,10 +5,7 @@ const { getAccountId, checkAndWarnGitInclusion, } = require('@hubspot/cli-lib'); -const { - ApiErrorContext, - logApiUploadErrorInstance, -} = require('@hubspot/cli-lib/errorHandlers'); +const { logger } = require('@hubspot/cli-lib/logger'); const { isAllowedExtension } = require('@hubspot/cli-lib/path'); const { LOG_LEVEL, @@ -22,6 +19,41 @@ checkAndWarnGitInclusion(getConfigPath()); const pluginName = 'HubSpotAutoUploadPlugin'; +const parseValidationErrors = (responseBody = {}) => { + const errorMessages = []; + + const { errors, message } = responseBody; + + if (message) { + errorMessages.push(message); + } + + if (errors) { + const specificErrors = errors.map(error => { + let errorMessage = error.message; + if (error.errorTokens && error.errorTokens.line) { + errorMessage = `line ${error.errorTokens.line}: ${errorMessage}`; + } + return errorMessage; + }); + errorMessages.push(...specificErrors); + } + + return errorMessages; +}; + +function logValidationErrors(error, context) { + const { response = {} } = error; + const validationErrors = parseValidationErrors(response.body); + if (validationErrors.length) { + validationErrors.forEach(err => { + logger.error(err); + }); + } + logger.debug(error); + logger.debug(context); +} + class HubSpotAutoUploadPlugin { constructor(options = {}) { const { src, dest, portal, account, autoupload } = options; @@ -67,14 +99,24 @@ class HubSpotAutoUploadPlugin { }) .catch(error => { webpackLogger.error(`Uploading ${dest} failed`); - logApiUploadErrorInstance( - error, - new ApiErrorContext({ - accountId: this.accountId, - request: dest, - payload: filepath, - }) - ); + const context = { + accountId: this.accountId, + request: dest, + payload: filepath, + statusCode: error.statusCode, + }; + if ( + error.statusCode === 400 && + error.response && + error.response.body && + (error.response.body.message || error.response.body.errors) + ) { + logValidationErrors(error, context); + } else { + console.error(error.message); + console.debug(error); + console.debug(context); + } }); }); }); From 38dec98ed6e228a62f8b6fa6c36e2653b3153665 Mon Sep 17 00:00:00 2001 From: Camden Phalen Date: Tue, 17 Oct 2023 11:52:05 -0400 Subject: [PATCH 4/7] Move copy in apiErrors to lang file --- packages/cli/lang/en.lyaml | 22 +++++++++ packages/cli/lib/errorHandlers/apiErrors.js | 55 ++++++++++++--------- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/packages/cli/lang/en.lyaml b/packages/cli/lang/en.lyaml index 7b5b7f3b5..a069b2619 100644 --- a/packages/cli/lang/en.lyaml +++ b/packages/cli/lang/en.lyaml @@ -1259,6 +1259,28 @@ en: label: "Lead Flows" marketing-email: label: "Marketing emails" + errorHandlers: + apiErrors: + messageDetail: "{{ request }} in account {{ accountId }}" + unableToUpload: 'Unable to upload "{{ payload }}.' + codes: + 400: "The {{ messageDetail }} was bad." + 401: "The {{ messageDetail }} was unauthorized." + 403MissingScope: "Couldn't run the project command because there are scopes missing in your production account. To update scopes, deactivate your current personal access key for {{ accountId }}, and generate a new one. Then run `hs auth` to update the CLI with the new key." + 403Gating: "The current target account {{ accountId }} does not have access to HubSpot projects. To opt in to the CRM Development Beta and use projects, visit https://app.hubspot.com/l/whats-new/betas?productUpdateId=13860216." + 403: "The {{ messageDetail }} was forbidden." + 404Request: 'The {{ action }} failed because "{{ request }}" was not found in account {{ accountId }}.' + 404: "The {{ messageDetail }} was not found." + 429: "The {{ messageDetail }} surpassed the rate limit. Retry in one minute." + 503: "The {{ messageDetail }} could not be handled at this time. Please try again or visit https://help.hubspot.com/ to submit a ticket or contact HubSpot Support if the issue persists." + 500generic: "The {{ messageDetail }} failed due to a server error. Please try again or visit https://help.hubspot.com/ to submit a ticket or contact HubSpot Support if the issue persists." + 400generic: "The {{ messageDetail }} failed due to a client error." + generic: "The {{ messageDetail }} failed." + verifyAccessKeyAndUserAccess: + fetchScopeDataError: "Error verifying access of scopeGroup {{ scopeGroup }}: {{ error }}" + portalMissingScope: "Your account does not have access to this action. Talk to an account admin to request it." + userMissingScope: "You don't have access to this action. Ask an account admin to change your permissions in Users & Teams settings." + genericMissingScope: "Your access key does not allow this action. Please generate a new access key by running `hs auth personalaccesskey`." diff --git a/packages/cli/lib/errorHandlers/apiErrors.js b/packages/cli/lib/errorHandlers/apiErrors.js index 8c68a2adb..509221064 100644 --- a/packages/cli/lib/errorHandlers/apiErrors.js +++ b/packages/cli/lib/errorHandlers/apiErrors.js @@ -12,6 +12,9 @@ const { logErrorInstance, ErrorContext, } = require('./standardErrors'); +const { i18n } = require('../lang'); + +const i18nKey = 'cli.lib.errorHandlers.apiErrors'; const isApiStatusCodeError = err => err.name === 'StatusCodeError' || @@ -64,9 +67,6 @@ const isSpecifiedHubSpotAuthError = ( ); }; -const contactSupportString = - 'Please try again or visit https://help.hubspot.com/ to submit a ticket or contact HubSpot Support if the issue persists.'; - const parseValidationErrors = (responseBody = {}) => { const errorMessages = []; @@ -174,52 +174,56 @@ function logApiStatusCodeError(error, context) { const isProjectGatingError = isGatingError(error) && projectName; switch (statusCode) { case 400: - errorMessage.push(`The ${messageDetail} was bad.`); + errorMessage.push(i18n(`${i18nKey}.codes.400`, { messageDetail })); break; case 401: - errorMessage.push(`The ${messageDetail} was unauthorized.`); + errorMessage.push(i18n(`${i18nKey}.codes.401`, { messageDetail })); break; case 403: if (isProjectMissingScopeError) { errorMessage.push( - `Couldn't run the project command because there are scopes missing in your production account. To update scopes, deactivate your current personal access key for ${context.accountId}, and generate a new one. Then run \`hs auth\` to update the CLI with the new key.` + i18n(`${i18nKey}.codes.403MissingScope`, { + accountId: context.accountId || '', + }) ); } else if (isProjectGatingError) { errorMessage.push( - `The current target account ${context.accountId} does not have access to HubSpot projects. To opt in to the CRM Development Beta and use projects, visit https://app.hubspot.com/l/whats-new/betas?productUpdateId=13860216.` + i18n(`${i18nKey}.codes.403Gating`, { + accountId: context.accountId || '', + }) ); } else { - errorMessage.push(`The ${messageDetail} was forbidden.`); + errorMessage.push(i18n(`${i18nKey}.codes.403`, { messageDetail })); } break; case 404: if (context.request) { errorMessage.push( - `The ${action} failed because "${context.request}" was not found in account ${context.accountId}.` + i18n(`${i18nKey}.codes.404Request`, { + action: action || 'request', + request: context.request, + account: context.accountId || '', + }) ); } else { - errorMessage.push(`The ${messageDetail} was not found.`); + errorMessage.push(i18n(`${i18nKey}.codes.404`, { messageDetail })); } break; case 429: - errorMessage.push( - `The ${messageDetail} surpassed the rate limit. Retry in one minute.` - ); + errorMessage.push(i18n(`${i18nKey}.codes.429`, { messageDetail })); break; case 503: - errorMessage.push( - `The ${messageDetail} could not be handled at this time. ${contactSupportString}` - ); + errorMessage.push(i18n(`${i18nKey}.codes.503`, { messageDetail })); break; default: if (statusCode >= 500 && statusCode < 600) { errorMessage.push( - `The ${messageDetail} failed due to a server error. ${contactSupportString}` + i18n(`${i18nKey}.codes.500Generic`, { messageDetail }) ); } else if (statusCode >= 400 && statusCode < 500) { - errorMessage.push(`The ${messageDetail} failed due to a client error.`); + i18n(`${i18nKey}.codes.400Generic`, { messageDetail }); } else { - errorMessage.push(`The ${messageDetail} failed.`); + errorMessage.push(i18n(`${i18nKey}.codes.generic`, { messageDetail })); } break; } @@ -280,26 +284,31 @@ async function verifyAccessKeyAndUserAccess(accountId, scopeGroup) { try { scopesData = await fetchScopeData(accountId, scopeGroup); } catch (e) { - logger.debug(`Error verifying access of scopeGroup ${scopeGroup}: ${e}`); + logger.debug( + i18n(`${i18nKey}.verifyAccessKeyAndUserAccess.fetchScopeDataError`, { + scopeGroup, + error: e, + }) + ); return; } const { portalScopesInGroup, userScopesInGroup } = scopesData; if (!portalScopesInGroup.length) { logger.error( - 'Your account does not have access to this action. Talk to an account admin to request it.' + i18n(`${i18nKey}.verifyAccessKeyAndUserAccess.portalMissingScope`) ); return; } if (!portalScopesInGroup.every(s => userScopesInGroup.includes(s))) { logger.error( - "You don't have access to this action. Ask an account admin to change your permissions in Users & Teams settings." + i18n(`${i18nKey}.verifyAccessKeyAndUserAccess.userMissingScope`) ); return; } else { logger.error( - 'Your access key does not allow this action. Please generate a new access key by running "hs auth personalaccesskey".' + i18n(`${i18nKey}.verifyAccessKeyAndUserAccess.genericMissingScope`) ); return; } From 72011d081b569d49e15469bd0d6466c73d016b0e Mon Sep 17 00:00:00 2001 From: Camden Phalen Date: Tue, 17 Oct 2023 12:07:29 -0400 Subject: [PATCH 5/7] Add standardErrors and fileSystemErrors copy to lang file --- packages/cli/lang/en.lyaml | 9 +++++ .../cli/lib/errorHandlers/fileSystemErrors.js | 9 +++-- .../cli/lib/errorHandlers/standardErrors.js | 36 +++++++++++-------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/packages/cli/lang/en.lyaml b/packages/cli/lang/en.lyaml index a069b2619..c88bc01cc 100644 --- a/packages/cli/lang/en.lyaml +++ b/packages/cli/lang/en.lyaml @@ -1260,6 +1260,15 @@ en: marketing-email: label: "Marketing emails" errorHandlers: + standardErrors: + errorOccurred: "Error: {{ error }}" + errorContext: "Context: {{ context }}" + systemErrorOccurred: "A system error has occured: {{ errorMessage }}" + genericErrorOccured: "A {{ name }} has occurred." + unknownErrorOccured: "An unknown error has occured" + fileSystemErrors: + errorOccured: "An error occurred while {{ fileAction }} {{ filepath }}." + errorExplanation: "This is the result of a system error: {{ errorMessage }}" apiErrors: messageDetail: "{{ request }} in account {{ accountId }}" unableToUpload: 'Unable to upload "{{ payload }}.' diff --git a/packages/cli/lib/errorHandlers/fileSystemErrors.js b/packages/cli/lib/errorHandlers/fileSystemErrors.js index d7d144887..bc22a06ee 100644 --- a/packages/cli/lib/errorHandlers/fileSystemErrors.js +++ b/packages/cli/lib/errorHandlers/fileSystemErrors.js @@ -4,6 +4,9 @@ const { isSystemError, debugErrorAndContext, } = require('./standardErrors'); +const { i18n } = require('../lang'); + +const i18nKey = 'cli.lib.errorHandlers.fileSystemErrors'; class FileSystemErrorContext extends ErrorContext { constructor(props = {}) { @@ -35,10 +38,12 @@ function logFileSystemErrorInstance(error, context) { const filepath = context.filepath ? `"${context.filepath}"` : 'a file or folder'; - const message = [`An error occurred while ${fileAction} ${filepath}.`]; + const message = [i18n(`${i18nKey}.errorOccured`, { fileAction, filepath })]; // Many `fs` errors will be `SystemError`s if (isSystemError(error)) { - message.push(`This is the result of a system error: ${error.message}`); + message.push( + i18n(`${i18nKey}.errorExplanation`, { errorMessage: error.message }) + ); } logger.error(message.join(' ')); debugErrorAndContext(error, context); diff --git a/packages/cli/lib/errorHandlers/standardErrors.js b/packages/cli/lib/errorHandlers/standardErrors.js index 9f36338a8..2045c2574 100644 --- a/packages/cli/lib/errorHandlers/standardErrors.js +++ b/packages/cli/lib/errorHandlers/standardErrors.js @@ -1,5 +1,8 @@ const { HubSpotAuthError } = require('@hubspot/cli-lib/lib/models/Errors'); const { logger } = require('@hubspot/cli-lib/logger'); +const { i18n } = require('../lang'); + +const i18nKey = 'cli.lib.errorHandlers.standardErrors'; const isSystemError = err => err.errno != null && err.code != null && err.syscall != null; @@ -22,18 +25,22 @@ class ErrorContext { function debugErrorAndContext(error, context) { if (error.name === 'StatusCodeError') { const { statusCode, message, response } = error; - logger.debug('Error: %o', { - statusCode, - message, - url: response.request.href, - method: response.request.method, - response: response.body, - headers: response.headers, - }); + logger.debug( + i18n(`${i18nKey}.errorOccured`, { + error: { + statusCode, + message, + url: response.request.href, + method: response.request.method, + response: response.body, + headers: response.headers, + }, + }) + ); } else { - logger.debug('Error: %o', error); + logger.debug(i18n(`${i18nKey}.errorOccured`, { error })); } - logger.debug('Context: %o', context); + logger.debug(i18n(`${i18nKey}.errorContect`, { context })); } /** @@ -44,7 +51,7 @@ function debugErrorAndContext(error, context) { * @param {ErrorContext} context */ function logSystemError(error, context) { - logger.error(`A system error has occurred: ${error.message}`); + logger.error(i18n(`${i18nKey}.systemErrorOccured`, { error: error.message })); debugErrorAndContext(error, context); } @@ -63,8 +70,9 @@ function logErrorInstance(error, context) { if (error instanceof Error || error.message || error.reason) { // Error or Error subclass const name = error.name || 'Error'; - const message = [`A ${name} has occurred.`]; - [error.message, error.reason].forEach(msg => { + const message = i18n(`${i18nKey}.genericErrorOcurred`, { name })[ + (error.message, error.reason) + ].forEach(msg => { if (msg) { message.push(msg); } @@ -72,7 +80,7 @@ function logErrorInstance(error, context) { logger.error(message.join(' ')); } else { // Unknown errors - logger.error(`An unknown error has occurred.`); + logger.error(i18n(`${i18nKey}.unknownErrorOcurred`)); } debugErrorAndContext(error, context); } From bc0ae4325e206f3b96646c22f72cbe89418c7736 Mon Sep 17 00:00:00 2001 From: Camden Phalen Date: Tue, 17 Oct 2023 12:10:53 -0400 Subject: [PATCH 6/7] fix typo --- packages/cli/lib/errorHandlers/standardErrors.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/cli/lib/errorHandlers/standardErrors.js b/packages/cli/lib/errorHandlers/standardErrors.js index 2045c2574..50801d913 100644 --- a/packages/cli/lib/errorHandlers/standardErrors.js +++ b/packages/cli/lib/errorHandlers/standardErrors.js @@ -70,9 +70,8 @@ function logErrorInstance(error, context) { if (error instanceof Error || error.message || error.reason) { // Error or Error subclass const name = error.name || 'Error'; - const message = i18n(`${i18nKey}.genericErrorOcurred`, { name })[ - (error.message, error.reason) - ].forEach(msg => { + const message = i18n(`${i18nKey}.genericErrorOcurred`, { name }); + [(error.message, error.reason)].forEach(msg => { if (msg) { message.push(msg); } From 26c3f869941585d785353f30674bfc7211106b11 Mon Sep 17 00:00:00 2001 From: Camden Phalen Date: Tue, 17 Oct 2023 12:33:51 -0400 Subject: [PATCH 7/7] fix more typos --- packages/cli/lib/errorHandlers/standardErrors.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/lib/errorHandlers/standardErrors.js b/packages/cli/lib/errorHandlers/standardErrors.js index 50801d913..5714053b7 100644 --- a/packages/cli/lib/errorHandlers/standardErrors.js +++ b/packages/cli/lib/errorHandlers/standardErrors.js @@ -70,7 +70,7 @@ function logErrorInstance(error, context) { if (error instanceof Error || error.message || error.reason) { // Error or Error subclass const name = error.name || 'Error'; - const message = i18n(`${i18nKey}.genericErrorOcurred`, { name }); + const message = [i18n(`${i18nKey}.genericErrorOccured`, { name })]; [(error.message, error.reason)].forEach(msg => { if (msg) { message.push(msg); @@ -79,7 +79,7 @@ function logErrorInstance(error, context) { logger.error(message.join(' ')); } else { // Unknown errors - logger.error(i18n(`${i18nKey}.unknownErrorOcurred`)); + logger.error(i18n(`${i18nKey}.unknownErrorOccured`)); } debugErrorAndContext(error, context); }