serverless/lib/classes/Error.test.js
Philipp Muens 1d4ef3b2b6 Add tests
2019-07-10 11:10:16 +02:00

178 lines
5.7 KiB
JavaScript

'use strict';
const expect = require('chai').expect;
const sandbox = require('sinon');
const overrideEnv = require('process-utils/override-env');
const errorReporter = require('../utils/sentry').raven;
const ServerlessError = require('./Error').ServerlessError;
const logError = require('./Error').logError;
const logWarning = require('./Error').logWarning;
describe('ServerlessError', () => {
describe('#constructor()', () => {
it('should store message', () => {
const error = new ServerlessError('a message', 'a status code');
expect(error.message).to.be.equal('a message');
});
it('should store name', () => {
const error = new ServerlessError('a message', 'a status code');
expect(error.name).to.be.equal('ServerlessError');
});
it('should store status code', () => {
const error = new ServerlessError('a message', 'a status code');
expect(error.statusCode).to.be.equal('a status code');
});
it('should have stack trace', () => {
let expectedError;
function testStackFrame() {
expectedError = new ServerlessError('a message', 'a status code');
throw expectedError;
}
let thrownError;
try {
testStackFrame();
} catch (e) {
thrownError = e;
}
expect(thrownError).to.exist; // eslint-disable-line no-unused-expressions
expect(thrownError).to.deep.equal(expectedError);
expect(thrownError.stack).to.exist; // eslint-disable-line no-unused-expressions
expect(thrownError.stack).to.have.string('testStackFrame');
expect(thrownError.stack).to.not.have.string('new ServerlessError');
expect(thrownError.stack).to.not.have.string('Error.js');
});
});
});
describe('Error', () => {
let consoleLogSpy;
let processExitStub;
let captureExceptionStub;
beforeEach(() => {
consoleLogSpy = sandbox.spy(console, 'log');
// the following is used so that the process exiting never interrupts tests
processExitStub = sandbox
.stub(process, 'exit')
.withArgs(1)
.returns();
captureExceptionStub = sandbox.stub(errorReporter, 'captureException').yields();
});
afterEach(() => {
sandbox.restore();
});
describe('#logError()', () => {
let restoreEnv;
beforeEach(() => ({ restoreEnv } = overrideEnv()));
afterEach(() => restoreEnv());
it('should log error and exit', () => {
const error = new ServerlessError('a message', 'a status code');
logError(error);
// TODO @David Not sure how to make async test for this
// If tracking enabled, the process exits in a callback and is not defined yet
// expect(this.processExitCodes.length).to.be.equal(1);
// expect(this.processExitCodes).gt(0);
const message = consoleLogSpy.args.join('\n');
expect(consoleLogSpy.called).to.equal(true);
expect(message).to.have.string('Serverless Error');
expect(message).to.have.string('a message');
});
it('should log environment information', () => {
const error = new ServerlessError('a message', 'a status code');
logError(error);
const message = consoleLogSpy.args.join('\n');
expect(consoleLogSpy.called).to.equal(true);
expect(message).to.have.string('Serverless Error');
expect(message).to.have.string('a message');
expect(message).to.have.string('Your Environment Information');
expect(message).to.have.string('Operating System:');
expect(message).to.have.string('Node Version:');
expect(message).to.have.string('Serverless Version:');
expect(message).to.have.string('Enterprise Plugin Version:');
expect(message).to.have.string('Platform SDK Version:');
});
it('should capture the exception and exit the process with 1 if errorReporter is setup', () => {
const error = new Error('an unexpected error');
logError(error);
expect(captureExceptionStub.args[0][0]).to.deep.equal(error);
expect(processExitStub.called).to.equal(true);
expect(processExitStub.calledWithExactly(1)).to.equal(true);
});
it('should notify about SLS_DEBUG and ask report for unexpected errors', () => {
const error = new Error('an unexpected error');
logError(error);
const message = consoleLogSpy.args.join('\n');
expect(consoleLogSpy.called).to.equal(true);
expect(message).to.have.string('SLS_DEBUG=*');
});
it('should print stack trace with SLS_DEBUG', () => {
process.env.SLS_DEBUG = '1';
const error = new ServerlessError('a message');
logError(error);
const message = consoleLogSpy.args.join('\n');
expect(consoleLogSpy.called).to.equal(true);
expect(message).to.have.string('Stack Trace');
expect(message).to.have.string(error.stack);
});
it('should not print stack trace without SLS_DEBUG', () => {
const error = new ServerlessError('a message');
logError(error);
const message = consoleLogSpy.args.join('\n');
expect(consoleLogSpy.called).to.equal(true);
expect(message).to.not.have.string('Stack Trace');
expect(message).to.not.have.string(error.stack);
});
it('should re-throw error when handling raises an exception itself', () => {
let thrownError = null;
try {
logError('INVALID INPUT');
} catch (e) {
thrownError = e;
}
expect(thrownError.message).to.equal("'INVALID INPUT'");
});
});
describe('#logWarning()', () => {
it('should log warning and proceed', () => {
logWarning('a message');
const message = consoleLogSpy.args.join('\n');
expect(consoleLogSpy.called).to.equal(true);
expect(message).to.have.string('Serverless Warning');
expect(message).to.have.string('a message');
});
});
});