Skip to content

Commit

Permalink
refactor: error module
Browse files Browse the repository at this point in the history
  • Loading branch information
sjinks committed Apr 15, 2024
1 parent a6fa909 commit 169fcb6
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 40 deletions.
25 changes: 5 additions & 20 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,38 +160,23 @@ module.exports = class Cli {
return formatters.formatOptions(omit);
};

// eslint-disable-next-line valid-jsdoc
/**
* Cli wrapper for error handler
*
* @since 3.0.0
* @alias lando.cli.handleError
* @param {Error} error The error
* @param {Function} handler The error handler function
* @param {Integer} verbose [verbose=this.argv().verbose] The verbosity level
* @param {import('./error')} handler The error handler function
* @param {number} verbose [verbose=this.argv().verbose] The verbosity level
* @param {Object} lando The Lando object
* @return {Integer} The exit codes
* @return {Promise<never>}
*/
handleError(error, handler, verbose = this.argv().verbose, lando = {}) {
// Set the verbosity
error.verbose = verbose;
// Ask question if we haven't sent error reporting yet
return lando.Promise.try(() => {
if (_.isNil(lando.cache.get('report_errors'))) {
const inquirer = require('inquirer');
console.error(this.makeArt('crash'));
const test = {
name: 'reportErrors',
type: 'confirm',
default: true,
message: 'Send crash reports?',
};
return inquirer.prompt([test]).then(answers => {
lando.cache.set('report_errors', answers.reportErrors, {persist: true});
});
}
})
// Report error if user has error reporting on
.then(() => handler.handle(error, lando.cache.get('report_errors')).then(code => process.exit(code)));
return handler.handle(error).then(code => process.exit(code));
};

/*
Expand Down
12 changes: 3 additions & 9 deletions lib/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

// Modules
const Log = require('./logger');
const Metrics = require('./metrics');

module.exports = class ErrorHandler {
constructor(log = new Log(), metrics = new Metrics()) {
constructor(log = new Log()) {
this.log = log;
this.metrics = metrics;
};

/**
Expand All @@ -18,14 +16,10 @@ module.exports = class ErrorHandler {
* @since 3.0.0
* @alias lando.error.handle
* @param {Object} error Error object
* @param {Boolean} report Whether to report the error or not
* @return {Integer} the error code
* @example
* // Gets all the pre-global options that have been specified.
* const argv = lando.tasks.argv();
* @return {Promise<number>} the error code
* @todo make this static and then fix all call sites
*/
handle({message, stack, code = 1, hide = false, verbose = 0} = {}, report = true) {
handle({message, stack, code = 1, hide = false, verbose = 0} = {}) {
// Log error or not
if (!hide) {
if (verbose > 0) this.log.error(stack);
Expand Down
2 changes: 1 addition & 1 deletion lib/lando.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ module.exports = class Lando {
this.cli = new Cli();
this.log = new Log(this.config);
this.metrics = bootstrap.setupMetrics(this.log, this.config);
this.error = new ErrorHandler(this.log, this.metrics),
this.error = new ErrorHandler(this.log);
this.events = new AsyncEvents(this.log);
this.user = require('./user');
};
Expand Down
17 changes: 7 additions & 10 deletions test/error.spec.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
/**
* Tests for table module.
* @file table.spec.js
* Tests for error module.
* @file error.spec.js
*/

'use strict';

const chai = require('chai');
const ErrorHandler = require('./../lib/error');
const EventEmitter = require('events').EventEmitter;
const Metrics = require('./../lib/metrics');
const Promise = require('./../lib/promise');
const sinon = require('sinon');
chai.should();
chai.use(require('chai-as-promised'));
Expand All @@ -20,42 +18,41 @@ describe('error', () => {
const error = new ErrorHandler();
error.should.be.instanceof(ErrorHandler);
error.log.should.be.instanceof(EventEmitter);
error.metrics.should.be.instanceof(Metrics);
});
});

describe('#handle', () => {
it('should return error code if specified', () => {
const error = new ErrorHandler({error: sinon.spy()}, {report: () => Promise.resolve(true)});
const error = new ErrorHandler({error: sinon.spy()});
return error.handle({message: 'trouble trouble trouble', stack: 'stack', code: 666}).then(code2 => {
code2.should.equal(666);
});
});

it('should return 1 if error code is not specified', () => {
const error = new ErrorHandler({error: sinon.spy()}, {report: () => Promise.resolve(true)});
const error = new ErrorHandler({error: sinon.spy()});
return error.handle({message: 'trouble trouble trouble', stack: 'stack'}).then(code1 => {
code1.should.equal(1);
});
});

it('should log message and report to metrics by default', () => {
const error = new ErrorHandler({error: sinon.spy()}, {report: () => Promise.resolve(true)});
const error = new ErrorHandler({error: sinon.spy()});
return error.handle().then(code => {
error.log.error.callCount.should.equal(1);
code.should.equal(1);
});
});

it('should not log error when error.hide is true', () => {
const error = new ErrorHandler({error: sinon.spy()}, {report: () => Promise.resolve(true)});
const error = new ErrorHandler({error: sinon.spy()});
return error.handle({message: 'super long; don\'t log', stack: 'stack', hide: true}).then(() => {
error.log.error.callCount.should.equal(0);
});
});

it('should log stack instead of message when error.verbose > 0', () => {
const error = new ErrorHandler({error: sinon.spy()}, {report: () => Promise.resolve(true)});
const error = new ErrorHandler({error: sinon.spy()});
return error.handle({message: 'message', stack: 'stack', verbose: 1, code: 4}).then(() => {
error.log.error.callCount.should.equal(1);
error.log.error.lastCall.args[0].should.equal('stack');
Expand Down

0 comments on commit 169fcb6

Please sign in to comment.