Error handling: add ExpectedError type as alternative to exitWithExpectedError()

Change-type: patch
Signed-off-by: Paulo Castro <paulo@balena.io>
This commit is contained in:
Paulo Castro
2019-10-31 01:40:57 +00:00
parent 268bc36843
commit a25a52c21b
3 changed files with 43 additions and 18 deletions

View File

@ -20,7 +20,9 @@ import * as _ from 'lodash';
import * as os from 'os'; import * as os from 'os';
import * as Raven from 'raven'; import * as Raven from 'raven';
import * as patterns from './utils/patterns'; export class ExpectedError extends Error {}
export class NotLoggedInError extends ExpectedError {}
const captureException = Bluebird.promisify<string, Error>( const captureException = Bluebird.promisify<string, Error>(
Raven.captureException, Raven.captureException,
@ -37,11 +39,7 @@ function treatFailedBindingAsMissingModule(error: any): void {
} }
} }
function interpret(error: any): string | undefined { function interpret(error: Error): string {
if (!(error instanceof Error)) {
return;
}
treatFailedBindingAsMissingModule(error); treatFailedBindingAsMissingModule(error);
if (hasCode(error)) { if (hasCode(error)) {
@ -55,9 +53,9 @@ function interpret(error: any): string | undefined {
if (!_.isEmpty(error.message)) { if (!_.isEmpty(error.message)) {
return `${error.code}: ${error.message}`; return `${error.code}: ${error.message}`;
} }
} else {
return error.message;
} }
return error.message;
} }
const messages: { const messages: {
@ -105,21 +103,35 @@ const messages: {
}; };
export async function handleError(error: any) { export async function handleError(error: any) {
let message = interpret(error); const { printErrorMessage } = await import('./utils/patterns');
if (message == null) {
process.exitCode =
error.exitCode === 0
? 0
: parseInt(error.exitCode, 10) || process.exitCode || 1;
if (!(error instanceof Error)) {
printErrorMessage(String(error));
return; return;
} }
if (process.env.DEBUG) { const message = [interpret(error)];
message = error.stack;
if (process.env.DEBUG && error.stack) {
message.push(error.stack);
}
printErrorMessage(message.join('\n'));
if (error instanceof ExpectedError) {
return;
} }
patterns.printErrorMessage(message!); // Report "unexpected" errors via Sentry.io
await captureException(error) await captureException(error)
.timeout(1000) .timeout(1000)
.catch(function() { .catch(function() {
// Ignore any errors (from error logging, or timeouts) // Ignore any errors (from error logging, or timeouts)
}) })
.finally(() => process.exit(error.exitCode || 1)); // exit with the process.exitCode set earlier
.finally(() => process.exit());
} }

View File

@ -18,7 +18,7 @@ export const getHelp = `${DEBUG_MODE ? '' : debugHint}\
If you need help, don't hesitate in contacting our support forums at If you need help, don't hesitate in contacting our support forums at
https://forums.balena.io https://forums.balena.io
For bug reports or feature requests, have a look at the GitHub issues or For CLI bug reports or feature requests, have a look at the GitHub issues or
create a new one at: https://github.com/balena-io/balena-cli/issues/\ create a new one at: https://github.com/balena-io/balena-cli/issues/\
`; `;

View File

@ -22,6 +22,7 @@ import _ = require('lodash');
import _form = require('resin-cli-form'); import _form = require('resin-cli-form');
import _visuals = require('resin-cli-visuals'); import _visuals = require('resin-cli-visuals');
import { NotLoggedInError } from '../errors';
import messages = require('./messages'); import messages = require('./messages');
import validation = require('./validation'); import validation = require('./validation');
@ -77,16 +78,28 @@ export function authenticate(options: {}): Bluebird<void> {
}); });
} }
export async function exitIfNotLoggedIn(): Promise<void> { export async function checkLoggedIn(): Promise<void> {
const balena = getBalenaSdk(); const balena = getBalenaSdk();
if (!(await balena.auth.isLoggedIn())) { if (!(await balena.auth.isLoggedIn())) {
exitWithExpectedError(stripIndent` throw new NotLoggedInError(stripIndent`
You have to log in to continue You have to log in to continue
Run the following command to go through the login wizard: Run the following command to go through the login wizard:
$ balena login`); $ balena login`);
} }
} }
export async function exitIfNotLoggedIn(): Promise<void> {
try {
await checkLoggedIn();
} catch (error) {
if (error instanceof NotLoggedInError) {
exitWithExpectedError(error);
} else {
throw error;
}
}
}
export function askLoginType() { export function askLoginType() {
return getForm().ask({ return getForm().ask({
message: 'How would you like to login?', message: 'How would you like to login?',