UNPKG

balena-cli

Version:

The official balena Command Line Interface

216 lines (213 loc) • 8.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.printExpectedErrorMessage = exports.printErrorMessage = exports.getSentry = exports.SIGINTError = exports.NoPortsDefinedError = exports.InvalidPortMappingError = exports.NotAvailableInOfflineModeError = exports.InsufficientPrivilegesError = exports.NotLoggedInError = exports.ExpectedError = void 0; exports.instanceOf = instanceOf; exports.handleError = handleError; const os = require("os"); const typed_error_1 = require("typed-error"); const lazy_1 = require("./utils/lazy"); const messages_1 = require("./utils/messages"); const bootstrap_1 = require("./utils/bootstrap"); class ExpectedError extends typed_error_1.TypedError { } exports.ExpectedError = ExpectedError; class NotLoggedInError extends ExpectedError { } exports.NotLoggedInError = NotLoggedInError; class InsufficientPrivilegesError extends ExpectedError { } exports.InsufficientPrivilegesError = InsufficientPrivilegesError; class NotAvailableInOfflineModeError extends ExpectedError { } exports.NotAvailableInOfflineModeError = NotAvailableInOfflineModeError; class InvalidPortMappingError extends ExpectedError { constructor(mapping) { super(`'${mapping}' is not a valid port mapping.`); } } exports.InvalidPortMappingError = InvalidPortMappingError; class NoPortsDefinedError extends ExpectedError { constructor() { super('No ports have been provided.'); } } exports.NoPortsDefinedError = NoPortsDefinedError; class SIGINTError extends ExpectedError { } exports.SIGINTError = SIGINTError; function instanceOf(err, klass) { var _a; if (err instanceof klass) { return true; } const name = err.name || ((_a = err.constructor) === null || _a === void 0 ? void 0 : _a.name); return name != null && name === klass.name; } function hasCode(error) { return error.code != null; } function treatFailedBindingAsMissingModule(error) { if (error.message.startsWith('Could not locate the bindings file.')) { error.code = 'MODULE_NOT_FOUND'; } } function interpret(error) { treatFailedBindingAsMissingModule(error); if (hasCode(error)) { const errorCodeHandler = messages[error.code]; const message = errorCodeHandler === null || errorCodeHandler === void 0 ? void 0 : errorCodeHandler(error); if (message) { return message; } if (typeof error.message === 'string' && error.message.length > 0) { return `${error.code}: ${error.message}`; } } return error.message; } function loadDataDirectory() { try { const settings = new bootstrap_1.CliSettings(); return settings.get('dataDirectory'); } catch (_a) { return os.platform() === 'win32' ? 'C:\\Users\\<user>\\_balena' : '$HOME/.balena'; } } const messages = { EISDIR: (error) => `File is a directory: ${error.path}`, ENOENT: (error) => `No such file or directory: ${error.path}`, ENOGIT: () => (0, lazy_1.stripIndent) ` Git is not installed on this system. Head over to http://git-scm.com to install it and run this command again.`, EPERM: () => (0, lazy_1.stripIndent) ` You don't have sufficient privileges to run this operation. ${os.platform() === 'win32' ? 'Run a new Command Prompt as administrator and try running this command again.' : 'Try running this command again prefixing it with `sudo`.'} If this is not the case, and you're trying to burn an SDCard, check that the write lock is not set.`, EACCES: (e) => messages.EPERM(e), BalenaSettingsPermissionError: () => { const dataDirectory = loadDataDirectory(); return (0, lazy_1.stripIndent) ` Error reading data directory: "${dataDirectory}" This error usually indicates that the user doesn't have permissions over that directory, which can happen if balena CLI was executed as the root user. ${os.platform() === 'win32' ? `Try resetting the ownership by opening a new Command Prompt as administrator and running: \`takeown /f ${dataDirectory} /r\`` : `Try resetting the ownership by running: \`sudo chown -R $(whoami) ${dataDirectory}\``} `; }, ETIMEDOUT: () => 'Oops something went wrong, please check your connection and try again.', MODULE_NOT_FOUND: () => (0, lazy_1.stripIndent) ` Part of the CLI could not be loaded. This typically means your CLI install is in a broken state. ${os.arch() === 'x64' ? 'You can normally fix this by uninstalling and reinstalling the CLI.' : (0, lazy_1.stripIndent) ` You're using an unsupported architecture (${os.arch()}), so this is typically caused by missing native modules. Reinstalling may help, but pay attention to errors in native module build steps en route. `} `, BalenaExpiredToken: () => (0, lazy_1.stripIndent) ` Looks like the session token has expired. Try logging in again with the "balena login" command.`, BalenaInvalidDeviceType: (error) => { if (typeof error.type === 'string' && error.type.startsWith('Incompatible ')) { return error.type; } const slug = error.deviceTypeSlug ? `"${error.deviceTypeSlug}"` : 'slug'; return (0, lazy_1.stripIndent) ` Device type ${slug} not recognized. Perhaps misspelled? Check available device types with "balena device-type list"`; }, }; const EXPECTED_ERROR_REGEXES = [ /cannot also be provided when using/, /^BalenaSettingsPermissionError/, /^BalenaAmbiguousApplication/, /^BalenaAmbiguousDevice/, /^BalenaApplicationNotFound/, /^BalenaDeviceNotFound/, /^BalenaExpiredToken/, /^BalenaInvalidDeviceType/, /^BalenaError: Release asset/, /^Release asset not found/, /Cannot deactivate devices/i, /Devices must be offline in order to be deactivated\.$/i, /^BalenaOrganizationNotFound/, /Request error: Unauthorized$/, /^Missing \d+ required arg/, /^Unexpected argument/, /to be one of/, /must also be provided when using/, /^Expected an integer/, /^Flag .* expects a value/, /^Error parsing config file.*balenarc\.yml/, ]; const getSentry = async function () { return await Promise.resolve().then(() => require('@sentry/node')); }; exports.getSentry = getSentry; async function sentryCaptureException(error) { const Sentry = await (0, exports.getSentry)(); Sentry.captureException(error); try { await Sentry.close(1000); } catch (_a) { if (process.env.DEBUG) { console.error('[debug] Timeout reporting error to sentry.io'); } } } async function handleError(error) { var _a; if (typeof error === 'string') { error = new Error(error); } const truncatedCode = Math.trunc(error.exitCode); process.exitCode = error.exitCode === 0 ? 0 : Number.isFinite(truncatedCode) ? truncatedCode : ((_a = process.exitCode) !== null && _a !== void 0 ? _a : 1); const message = [interpret(error)]; if (error.stack && process.env.DEBUG) { message.push('\n' + error.stack); } const isExpectedError = error instanceof ExpectedError || EXPECTED_ERROR_REGEXES.some((re) => re.test(message[0])) || EXPECTED_ERROR_REGEXES.some((re) => re.test(error.code)); if (isExpectedError) { (0, exports.printExpectedErrorMessage)(message.join('\n')); } else { (0, exports.printErrorMessage)(message.join('\n')); if (!process.env.BALENARC_NO_SENTRY) { await sentryCaptureException(error); } } if (error instanceof SIGINTError || !isExpectedError) { process.exit(); } } const printErrorMessage = function (message) { var _a; const ux = (0, lazy_1.getCliUx)(); const messageLines = message.split('\n'); console.error(ux.colorize('red', (_a = messageLines.shift()) !== null && _a !== void 0 ? _a : '')); messageLines.forEach((line) => { console.error(line); }); console.error(`\n${(0, messages_1.getHelp)()}\n`); }; exports.printErrorMessage = printErrorMessage; const printExpectedErrorMessage = function (message) { console.error(`${message}\n`); }; exports.printExpectedErrorMessage = printExpectedErrorMessage; //# sourceMappingURL=errors.js.map