mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-04-08 03:44:13 +00:00
Recategorize some errors as expected.
Change-type: patch Signed-off-by: Scott Lowe <scott@balena.io>
This commit is contained in:
parent
17089a35c3
commit
1308b64c67
2
lib/actions-oclif/env/add.ts
vendored
2
lib/actions-oclif/env/add.ts
vendored
@ -117,7 +117,7 @@ export default class EnvAddCmd extends Command {
|
||||
params.value = process.env[params.name];
|
||||
|
||||
if (params.value == null) {
|
||||
throw new Error(
|
||||
throw new ExpectedError(
|
||||
`Value not found for environment variable: ${params.name}`,
|
||||
);
|
||||
} else if (!options.quiet) {
|
||||
|
@ -51,7 +51,7 @@ const deployProject = function (docker, logger, composeOpts, opts) {
|
||||
project.descriptors.length > 1 &&
|
||||
!opts.app.application_type?.[0]?.supports_multicontainer
|
||||
) {
|
||||
throw new Error(
|
||||
throw new ExpectedError(
|
||||
'Target application does not support multiple containers. Aborting!',
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 Balena
|
||||
Copyright 2017-2020 Balena Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -16,7 +16,9 @@ limitations under the License.
|
||||
|
||||
import type { CommandDefinition } from 'capitano';
|
||||
import type * as SDK from 'etcher-sdk';
|
||||
|
||||
import { getChalk, getVisuals, stripIndent } from '../../utils/lazy';
|
||||
import { ExpectedError } from '../../errors';
|
||||
|
||||
async function getDrive(options: {
|
||||
drive?: string;
|
||||
@ -31,7 +33,7 @@ async function getDrive(options: {
|
||||
try {
|
||||
const d = scanner.getBy('device', drive);
|
||||
if (d === undefined || !(d instanceof sdk.sourceDestination.BlockDevice)) {
|
||||
throw new Error(`Drive not found: ${options.drive}`);
|
||||
throw new ExpectedError(`Drive not found: ${options.drive}`);
|
||||
}
|
||||
return d;
|
||||
} finally {
|
||||
|
@ -21,6 +21,7 @@ import { createServer, Server, Socket } from 'net';
|
||||
import { getBalenaSdk, stripIndent } from '../utils/lazy';
|
||||
import { getOnlineTargetUuid } from '../utils/patterns';
|
||||
import { tunnelConnectionToDevice } from '../utils/tunnel';
|
||||
import { ExpectedError } from '../errors';
|
||||
|
||||
interface Args {
|
||||
deviceOrApplication: string;
|
||||
@ -223,7 +224,7 @@ export const tunnel: CommandDefinition<Args, Options> = {
|
||||
|
||||
const results = await Promise.all(localListeners);
|
||||
if (!results.includes(true)) {
|
||||
throw new Error('No ports are valid for tunnelling');
|
||||
throw new ExpectedError('No ports are valid for tunnelling');
|
||||
}
|
||||
|
||||
logger.logInfo('Waiting for connections...');
|
||||
|
@ -21,6 +21,7 @@ import type { Socket } from 'net';
|
||||
import * as path from 'path';
|
||||
|
||||
import * as utils from './utils';
|
||||
import { ExpectedError } from '../errors';
|
||||
|
||||
const serverSockets: Socket[] = [];
|
||||
|
||||
@ -87,11 +88,11 @@ export const awaitForToken = (options: {
|
||||
try {
|
||||
const token = request.body.token?.trim();
|
||||
if (!token) {
|
||||
throw new Error('No token');
|
||||
throw new ExpectedError('No token');
|
||||
}
|
||||
const loggedIn = await utils.loginIfTokenValid(token);
|
||||
if (!loggedIn) {
|
||||
throw new Error('Invalid token');
|
||||
throw new ExpectedError('Invalid token');
|
||||
}
|
||||
response.status(200).render('success');
|
||||
resolve(token);
|
||||
|
@ -355,7 +355,7 @@ async function parseRegistrySecrets(
|
||||
if (/.+\.ya?ml$/i.test(secretsFilename)) {
|
||||
isYaml = true;
|
||||
} else if (!/.+\.json$/i.test(secretsFilename)) {
|
||||
throw new Error('Filename must end with .json, .yml or .yaml');
|
||||
throw new ExpectedError('Filename must end with .json, .yml or .yaml');
|
||||
}
|
||||
const raw = (await fs.readFile(secretsFilename)).toString();
|
||||
const registrySecrets = new MultiBuild.RegistrySecretValidator().validateRegistrySecrets(
|
||||
@ -459,7 +459,7 @@ async function performResolution(
|
||||
(clonedStream: tar.Pack) => {
|
||||
buildTask.buildStream = clonedStream;
|
||||
if (!buildTask.external && !buildTask.resolved) {
|
||||
throw new Error(
|
||||
throw new ExpectedError(
|
||||
`Project type for service "${buildTask.serviceName}" could not be determined. Missing a Dockerfile?`,
|
||||
);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
import * as Bluebird from 'bluebird';
|
||||
import * as _ from 'lodash';
|
||||
import { ExpectedError } from '../errors';
|
||||
|
||||
// Use this function to seed an action's list of capitano options
|
||||
// with the docker options. Using this interface means that
|
||||
@ -122,7 +123,7 @@ const generateConnectOpts = function (opts) {
|
||||
connectOpts.port = opts.dockerPort || 2376;
|
||||
} else if (opts.docker != null && opts.dockerHost != null) {
|
||||
// Both provided, no obvious way to continue
|
||||
throw new Error(
|
||||
throw new ExpectedError(
|
||||
"Both a local docker socket and docker host have been provided. Don't know how to continue.",
|
||||
);
|
||||
} else {
|
||||
@ -142,7 +143,7 @@ const generateConnectOpts = function (opts) {
|
||||
if (opts.ca != null || opts.cert != null || opts.key != null) {
|
||||
// but not all
|
||||
if (!(opts.ca != null && opts.cert != null && opts.key != null)) {
|
||||
throw new Error(
|
||||
throw new ExpectedError(
|
||||
'You must provide a CA, certificate and key in order to use TLS',
|
||||
);
|
||||
}
|
||||
@ -172,7 +173,7 @@ const parseBuildArgs = function (args) {
|
||||
if (pair != null) {
|
||||
buildArgs[pair[1]] = pair[2] ?? '';
|
||||
} else {
|
||||
throw new Error(`Could not parse build argument: '${arg}'`);
|
||||
throw new ExpectedError(`Could not parse build argument: '${arg}'`);
|
||||
}
|
||||
});
|
||||
return buildArgs;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016-2020 Balena
|
||||
Copyright 2016-2020 Balena Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -19,10 +19,14 @@ import Bluebird = require('bluebird');
|
||||
import _ = require('lodash');
|
||||
import _form = require('resin-cli-form');
|
||||
|
||||
import { exitWithExpectedError, instanceOf, NotLoggedInError } from '../errors';
|
||||
import {
|
||||
exitWithExpectedError,
|
||||
instanceOf,
|
||||
NotLoggedInError,
|
||||
ExpectedError,
|
||||
} from '../errors';
|
||||
import { getBalenaSdk, getVisuals, stripIndent } from './lazy';
|
||||
import validation = require('./validation');
|
||||
import { isV12 } from './version';
|
||||
|
||||
const getForm = _.once((): typeof _form => require('resin-cli-form'));
|
||||
|
||||
@ -65,7 +69,7 @@ export function authenticate(options: {}): Bluebird<void> {
|
||||
error.name === 'BalenaRequestError' &&
|
||||
error.statusCode === 401
|
||||
) {
|
||||
throw new Error('Invalid two factor authentication code');
|
||||
throw new ExpectedError('Invalid two factor authentication code');
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
@ -80,16 +84,9 @@ export function authenticate(options: {}): Bluebird<void> {
|
||||
export async function checkLoggedIn(): Promise<void> {
|
||||
const balena = getBalenaSdk();
|
||||
if (!(await balena.auth.isLoggedIn())) {
|
||||
if (isV12()) {
|
||||
throw new NotLoggedInError(stripIndent`
|
||||
Login required: use the “balena login” command to log in.
|
||||
`);
|
||||
} else {
|
||||
throw new NotLoggedInError(stripIndent`
|
||||
You have to log in to continue
|
||||
Run the following command to go through the login wizard:
|
||||
$ balena login`);
|
||||
}
|
||||
throw new NotLoggedInError(stripIndent`
|
||||
Login required: use the “balena login” command to log in.
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +172,7 @@ export function selectApplication(
|
||||
.hasAny()
|
||||
.then(function (hasAnyApplications) {
|
||||
if (!hasAnyApplications) {
|
||||
throw new Error("You don't have any applications");
|
||||
throw new ExpectedError("You don't have any applications");
|
||||
}
|
||||
|
||||
return balena.models.application.getAll();
|
||||
@ -316,7 +313,7 @@ export function inferOrSelectDevice(preferredUuid: string) {
|
||||
.filter<BalenaSdk.Device>((device) => device.is_online)
|
||||
.then((onlineDevices) => {
|
||||
if (_.isEmpty(onlineDevices)) {
|
||||
throw new Error("You don't have any devices online");
|
||||
throw new ExpectedError("You don't have any devices online");
|
||||
}
|
||||
|
||||
const defaultUuid = _(onlineDevices).map('uuid').includes(preferredUuid)
|
||||
@ -348,7 +345,9 @@ export async function getOnlineTargetUuid(
|
||||
const uuidTest = validation.validateUuid(applicationOrDevice);
|
||||
|
||||
if (!appTest && !uuidTest) {
|
||||
throw new Error(`Device or application not found: ${applicationOrDevice}`);
|
||||
throw new ExpectedError(
|
||||
`Device or application not found: ${applicationOrDevice}`,
|
||||
);
|
||||
}
|
||||
|
||||
// if we have a definite device UUID...
|
||||
@ -375,7 +374,7 @@ export async function getOnlineTargetUuid(
|
||||
});
|
||||
|
||||
if (_.isEmpty(devices)) {
|
||||
throw new Error('No accessible devices are online');
|
||||
throw new ExpectedError('No accessible devices are online');
|
||||
}
|
||||
|
||||
return await getForm().ask({
|
||||
|
@ -180,7 +180,7 @@ async function getOrSelectLocalDevice(deviceIp?: string): Promise<string> {
|
||||
});
|
||||
|
||||
if (!ip) {
|
||||
throw new Error('No device selected');
|
||||
throw new ExpectedError('No device selected');
|
||||
}
|
||||
|
||||
return ip;
|
||||
@ -211,7 +211,7 @@ async function getOrSelectApplication(
|
||||
const allDeviceTypes = await sdk.models.config.getDeviceTypes();
|
||||
const deviceTypeManifest = _.find(allDeviceTypes, { slug: deviceType });
|
||||
if (!deviceTypeManifest) {
|
||||
throw new Error(`"${deviceType}" is not a valid device type`);
|
||||
throw new ExpectedError(`"${deviceType}" is not a valid device type`);
|
||||
}
|
||||
const compatibleDeviceTypes = _(allDeviceTypes)
|
||||
.filter(
|
||||
@ -274,7 +274,7 @@ async function getOrSelectApplication(
|
||||
);
|
||||
|
||||
if (validApplications.length === 0) {
|
||||
throw new Error('No application found with a matching device type');
|
||||
throw new ExpectedError('No application found with a matching device type');
|
||||
}
|
||||
|
||||
if (validApplications.length === 1) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user