Skip to content

Commit

Permalink
refactor: Add custom module errors, better error handling, remove dep…
Browse files Browse the repository at this point in the history
…recated tests
  • Loading branch information
oleg-koval committed Jan 17, 2018
1 parent c4180f2 commit 16b6338
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 81 deletions.
36 changes: 36 additions & 0 deletions error/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* TrembitaError constructor
*
* @param {String} msg Error message
* @inherits Error https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error
*/

function TrembitaError(msg) {
Error.call(this);
if (Error.captureStackTrace) {
Error.captureStackTrace(this);
} else {
this.stack = new Error().stack;
}
this.message = msg;
Object.defineProperty(this, 'name', { value: this.constructor.name })
}

/*!
* Inherits from Error.
*/

TrembitaError.prototype = Object.create(Error.prototype);
TrembitaError.prototype.constructor = Error;

/*!
* Module exports.
*/

module.exports = exports = TrembitaError;

/*!
* Expose subclasses
*/

TrembitaError.UnexpectedStatusCodeError = require('./unexpectedStatusCodeError');
78 changes: 78 additions & 0 deletions error/unexpectedStatusCodeError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*!
* Module requirements
*/
const util = require('util');
const TrembitaError = require('./');

/**
* Unexpected StatusCode Error
*
* @api private
* @param {Document} instance
* @inherits TrembitaError
*/

function UnexpectedStatusCodeError(instance) {
this.message = '';

if (instance && instance.constructor.name === 'Object') {
this.message = _generateErrorMessage(instance)
TrembitaError.call(this, this.message);
} else {
this.message = 'Unexpected Status Code Error';
TrembitaError.call(this, this.message);
}

this.name = 'UnexpectedStatusCodeError';
if (Error.captureStackTrace) {
Error.captureStackTrace(this);
} else {
this.stack = new Error().stack;
}
}

/*!
* Inherits from TrembitaError.
*/

UnexpectedStatusCodeError.prototype = Object.create(TrembitaError.prototype);
UnexpectedStatusCodeError.prototype.constructor = TrembitaError;

/**
* Console.log helper
*/

UnexpectedStatusCodeError.prototype.toString = function() {
return this.name + ': ' + _generateErrorMessage(this);
};

/*!
* inspect helper
*/

UnexpectedStatusCodeError.prototype.inspect = function() {
return Object.assign(new Error(this.message), this);
};

/*!
* Helper for JSON.stringify
*/

UnexpectedStatusCodeError.prototype.toJSON = function() {
return Object.assign({}, this, { message: this.message });
};

/*!
* ignore
*/

function _generateErrorMessage (instance) {
return `${`Unexpected status code: ${instance.httpStatusCode}, Body: ${util.inspect(instance.httpBody, { depth: 4 })}, Options: `}${util.inspect(instance.options, { depth: 4 })}`
}


/*!
* Module exports
*/

module.exports = exports = UnexpectedStatusCodeError;
27 changes: 14 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
const Promise = require('bluebird');

const {
generateErrorMessage
} = require('./units');
const request = Promise.promisify(require('request'));

const RequestClient = class RequestClient {
const { UnexpectedStatusCodeError } = require('./error');

const Trembita = class Trembita {
constructor(options) {
this.raw = options => {
const expectedCodes = options.expectedCodes || [200];
return this.client(options)
.then(res => {
if (!expectedCodes.includes(res.statusCode)) {
const msg = generateErrorMessage(res, options)
const error = new Error(msg);
error.httpStatusCode = res.statusCode;
error.httpBody = res.body;
throw new Error(error);
const error = new UnexpectedStatusCodeError({
options,
httpStatusCode: res.statusCode,
httpBody: res.body
});
return Promise.reject(error)
}
if (res.body === undefined) {
res.body = null
}
return res.body;
})
.catch(this.log.error)
}
this.request = options => this.raw(options);
this.request = options => {
this.log.trace({ options }, 'request')
return this.raw(options)
};
if (!options.endpoint) {
throw new Error('no endpoint');
}
Expand All @@ -39,4 +40,4 @@ const RequestClient = class RequestClient {
}
};

module.exports = RequestClient;
module.exports = Trembita;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"main": "index.js",
"scripts": {
"test": "mocha",
"lint": "eslint *.js",
"lint": "eslint index.js",
"ci": "npm run lint && npm run test"
},
"author": "Oleg Koval <[email protected]> (http://wearereasonablepeople.com/)",
Expand Down
7 changes: 5 additions & 2 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const nock = require('nock');
const helpers = require('./helpers');

const Trembita = require('../');
const { UnexpectedStatusCodeError } = require('../error');

describe('Trembita:', () => {
let scope;
Expand Down Expand Up @@ -88,8 +89,10 @@ describe('Trembita:', () => {
url: '/profiles/1',
expectedCodes: [200]
})
.catch(err => {
expect(err).to.throw
.catch(UnexpectedStatusCodeError, (err) => {
const message = `Unexpected status code: 404, Body: undefined, Options: { url: \'/profiles/1\', expectedCodes: [ 200 ] }`
expect(err.message).to.equal(message)
expect(err.toJSON()).to.deep.equal({ message })
})
});
});
45 changes: 0 additions & 45 deletions test/units.js

This file was deleted.

20 changes: 0 additions & 20 deletions units.js

This file was deleted.

0 comments on commit 16b6338

Please sign in to comment.