Skip to content

Commit

Permalink
misc
Browse files Browse the repository at this point in the history
  • Loading branch information
Eran Hammer committed Feb 8, 2013
1 parent 534862e commit c56a9f8
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 118 deletions.
150 changes: 64 additions & 86 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,88 +9,84 @@ var Hoek = require('hoek');

var internals = {};

/*
Boom(new Error)
Boom(code, message)
*/

exports = module.exports = internals.Error = function (code, message) {
exports = module.exports = internals.Boom = function () {

var self = this;

Hoek.assert(this.constructor === internals.Error, 'Error must be instantiated using new');
Hoek.assert(code instanceof Error || (!isNaN(parseFloat(code)) && isFinite(code) && code >= 400), 'code must be an Error or a number (400+)');
Hoek.assert(this.constructor === internals.Boom, 'Error must be instantiated using new');

Error.call(this);

if (code instanceof Error) {
for (var d in code) {
if (code.hasOwnProperty(d)) {
this[d] = code[d];
}
}
this.response = {
code: 0,
payload: {},
headers: {}
// type: 'content-type'
};

this.code = this.code || 500;
this.name = code.name;
this.message = code.message || message;
if (code.message && message) {
this.info = message;
}
if (arguments[0] instanceof Error) {

this.toResponse = code.toResponse; // Required if toRepsonse is a prototype function
// Error

var error = arguments[0];

this.data = error;
this.response.code = error.code || 500;
if (error.message) {
this.message = error.message
}
}
else {
this.code = code;
this.message = message;
}

// Response format
// code, message

if (!this.toResponse ||
typeof this.toResponse !== 'function') {
var code = arguments[0];
var message = arguments[1];

this.toResponse = internals.toResponse;
}
Hoek.assert(!isNaN(parseFloat(code)) && isFinite(code) && code >= 400, 'First argument must be a number (400+)');

return this;
};
this.response.code = code;
if (message) {
this.message = message
}
}

NodeUtil.inherits(internals.Error, Error);
// Response format

this.reformat();

internals.toResponse = function () {
return this;
};

// { code, payload, type, headers }
NodeUtil.inherits(internals.Boom, Error);

var response = {
code: this.code,
payload: {
error: Http.STATUS_CODES[this.code] || 'Unknown',
code: this.code,
message: this.message
}
};

for (var d in this) {
if (['error', 'code', 'message'].indexOf(d) === -1 &&
this.hasOwnProperty(d) &&
typeof this[d] !== 'function') {
internals.Boom.prototype.reformat = function () {

response.payload[d] = this[d];
}
this.response.payload.code = this.response.code;
this.response.payload.error = Http.STATUS_CODES[this.response.code] || 'Unknown';
if (this.message) {
this.response.payload.message = this.message;
}

return response;
};


// Utilities

internals.Error.badRequest = function (message) {
internals.Boom.badRequest = function (message) {

return new internals.Error(400, message);
return new internals.Boom(400, message);
};


internals.Error.unauthorized = function (error, scheme, attributes) { // Or function (error, wwwAuthenticate[])
internals.Boom.unauthorized = function (error, scheme, attributes) { // Or function (error, wwwAuthenticate[])

var err = new internals.Error(401, error);
var err = new internals.Boom(401, error);

if (!scheme) {
return err;
Expand Down Expand Up @@ -144,79 +140,61 @@ internals.Error.unauthorized = function (error, scheme, attributes) {
}
}

err.toResponse = function () {

var response = internals.toResponse.call(this);
response.headers = { 'WWW-Authenticate': wwwAuthenticate };
return response;
};
err.response.headers['WWW-Authenticate'] = wwwAuthenticate;

return err;
};


internals.Error.clientTimeout = function (message) {
internals.Boom.clientTimeout = function (message) {

return new internals.Error(408, message);
return new internals.Boom(408, message);
};


internals.Error.serverTimeout = function (message) {
internals.Boom.serverTimeout = function (message) {

return new internals.Error(503, message);
return new internals.Boom(503, message);
};


internals.Error.forbidden = function (message) {
internals.Boom.forbidden = function (message) {

return new internals.Error(403, message);
return new internals.Boom(403, message);
};


internals.Error.notFound = function (message) {
internals.Boom.notFound = function (message) {

return new internals.Error(404, message);
return new internals.Boom(404, message);
};


internals.Error.internal = function (message, data) {
internals.Boom.internal = function (message, data) {

var err = new internals.Error(500, message);
var err = new internals.Boom(500, message);
err.trace = Hoek.displayStack(1);
err.data = data;

err.toResponse = function () {

var response = internals.toResponse.call(this);
response.payload.message = 'An internal server error occurred'; // Hide actual error from user
return response;
};
err.response.payload.message = 'An internal server error occurred'; // Hide actual error from user

return err;
};


internals.Error.passThrough = function (code, payload, contentType, headers) {
internals.Boom.passThrough = function (code, payload, contentType, headers) {

var err = new internals.Error(500, 'Pass-through'); // 500 code is only used internally and is not exposed when sent
var err = new internals.Boom(500, 'Pass-through'); // 500 code is only used to initialize

err.passThrough = {
err.data = {
code: code,
payload: payload,
type: contentType
};

err.toResponse = function () {

var response = {
code: code,
payload: payload,
type: contentType,
headers: headers
};

return response;
};
err.response.code = code;
err.response.type = contentType;
err.response.headers = headers;
err.response.payload = payload;

return err;
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "boom",
"description": "HTTP-friendly error objects",
"version": "0.2.1",
"version": "0.3.0",
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",
"contributors": [],
"repository": "git://github.com/hueniverse/boom",
Expand Down
59 changes: 28 additions & 31 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,21 @@ var expect = Chai.expect;

describe('Boom', function () {

it('returns an error with info when constructed using another error and message', function (done) {
it('returns an error with info when constructed using another error', function (done) {

var error = new Error('inner');
var error = new Error('ka-boom');
error.xyz = 123;
var err = new Boom(error, 'outter');
expect(err.message).to.equal('inner');
expect(err.info).to.equal('outter');
expect(err.xyz).to.equal(123);
expect(err.toResponse()).to.deep.equal({
var err = new Boom(error);
expect(err.data.xyz).to.equal(123);
expect(err.message).to.equal('ka-boom');
expect(err.response).to.deep.equal({
code: 500,
payload: {
error: 'Internal Server Error',
code: 500,
message: 'inner',
xyz: 123,
name: 'Error',
info: 'outter'
}
error: 'Internal Server Error',
message: 'ka-boom'
},
headers: {}
});
done();
});
Expand All @@ -42,7 +39,7 @@ describe('Boom', function () {

it('returns a 400 error code', function (done) {

expect(Boom.badRequest().code).to.equal(400);
expect(Boom.badRequest().response.code).to.equal(400);
done();
});

Expand All @@ -58,8 +55,8 @@ describe('Boom', function () {
it('returns a 401 error code', function (done) {

var err = Boom.unauthorized();
expect(err.code).to.equal(401);
expect(err.toResponse().headers).to.not.exist;
expect(err.response.code).to.equal(401);
expect(err.response.headers).to.deep.equal({});
done();
});

Expand All @@ -72,16 +69,16 @@ describe('Boom', function () {
it('returns a WWW-Authenticate header when passed a scheme', function (done) {

var err = Boom.unauthorized('boom', 'Test');
expect(err.code).to.equal(401);
expect(err.toResponse().headers['WWW-Authenticate']).to.equal('Test error="boom"');
expect(err.response.code).to.equal(401);
expect(err.response.headers['WWW-Authenticate']).to.equal('Test error="boom"');
done();
});

it('returns a WWW-Authenticate header when passed a scheme and attributes', function (done) {

var err = Boom.unauthorized('boom', 'Test', { a: 1, b: 'something', c: null, d: 0 });
expect(err.code).to.equal(401);
expect(err.toResponse().headers['WWW-Authenticate']).to.equal('Test a="1", b="something", c="", d="0", error="boom"');
expect(err.response.code).to.equal(401);
expect(err.response.headers['WWW-Authenticate']).to.equal('Test a="1", b="something", c="", d="0", error="boom"');
done();
});

Expand All @@ -102,7 +99,7 @@ describe('Boom', function () {
it('sets a WWW-Authenticate when passed as an array', function (done) {

var err = Boom.unauthorized('message', ['Basic', 'Example e="1"', 'Another x="3", y="4"']);
expect(err.toResponse().headers['WWW-Authenticate']).to.equal('Basic, Example e="1", Another x="3", y="4"');
expect(err.response.headers['WWW-Authenticate']).to.equal('Basic, Example e="1", Another x="3", y="4"');
done();
});
});
Expand All @@ -111,7 +108,7 @@ describe('Boom', function () {

it('returns a 408 error code', function (done) {

expect(Boom.clientTimeout().code).to.equal(408);
expect(Boom.clientTimeout().response.code).to.equal(408);
done();
});

Expand All @@ -126,7 +123,7 @@ describe('Boom', function () {

it('returns a 503 error code', function (done) {

expect(Boom.serverTimeout().code).to.equal(503);
expect(Boom.serverTimeout().response.code).to.equal(503);
done();
});

Expand All @@ -141,7 +138,7 @@ describe('Boom', function () {

it('returns a 403 error code', function (done) {

expect(Boom.forbidden().code).to.equal(403);
expect(Boom.forbidden().response.code).to.equal(403);
done();
});

Expand All @@ -156,7 +153,7 @@ describe('Boom', function () {

it('returns a 404 error code', function (done) {

expect(Boom.notFound().code).to.equal(404);
expect(Boom.notFound().response.code).to.equal(404);
done();
});

Expand All @@ -171,15 +168,15 @@ describe('Boom', function () {

it('returns a 500 error code', function (done) {

expect(Boom.internal().code).to.equal(500);
expect(Boom.internal().response.code).to.equal(500);
done();
});

it('sets the message with the passed in message', function (done) {

var err = Boom.internal('my message');
expect(err.message).to.equal('my message');
expect(err.toResponse().payload.message).to.equal('An internal server error occurred');
expect(err.response.payload.message).to.equal('An internal server error occurred');
done();
});

Expand All @@ -195,13 +192,13 @@ describe('Boom', function () {
it('returns a pass-through error', function (done) {

var err = Boom.passThrough(499, { a: 1 }, 'application/text', { 'X-Test': 'Boom' });
expect(err.code).to.equal(500);
expect(err.response.code).to.equal(499);
expect(err.message).to.equal('Pass-through');
expect(err.toResponse()).to.deep.equal({
expect(err.response).to.deep.equal({
code: 499,
payload: { a: 1 },
type: 'application/text',
headers: { 'X-Test': 'Boom' }
headers: { 'X-Test': 'Boom' },
type: 'application/text'
});
done();
});
Expand Down

0 comments on commit c56a9f8

Please sign in to comment.