Include err.message and err.name for debug data

err.message and err.name are not enumerable,
therefore needs to be explicited added to the data obj
This commit is contained in:
David Cheung 2016-05-16 10:57:15 -04:00
parent a5129595ef
commit ef72b5c0f1
2 changed files with 45 additions and 16 deletions

View File

@ -16,9 +16,10 @@ module.exports = function buildResponseData(err, isDebugMode) {
fillStatusCode(data, err); fillStatusCode(data, err);
if (typeof err !== 'object') { if (typeof err !== 'object') {
data.statusCode = 500; err = {
data.message = '' + err; statusCode: 500,
err = {}; message: '' + err,
};
} }
if (isDebugMode) { if (isDebugMode) {
@ -41,10 +42,8 @@ function serializeArrayOfErrors(errors) {
continue; continue;
} }
var data = {stack: err.stack}; var data = {};
for (var p in err) { // eslint-disable-line one-var cloneAllProperties(data, err);
data[p] = err[p];
}
details.push(data); details.push(data);
} }
@ -63,12 +62,7 @@ function fillStatusCode(data, err) {
} }
function fillDebugData(data, err) { function fillDebugData(data, err) {
for (var p in err) { cloneAllProperties(data, err);
if ((p in data)) continue;
data[p] = err[p];
}
// NOTE err.stack is not an enumerable property
data.stack = err.stack;
} }
function fillBadRequestError(data, err) { function fillBadRequestError(data, err) {
@ -80,3 +74,16 @@ function fillBadRequestError(data, err) {
function fillInternalError(data, err) { function fillInternalError(data, err) {
data.message = httpStatus[data.statusCode] || 'Unknown Error'; data.message = httpStatus[data.statusCode] || 'Unknown Error';
} }
function cloneAllProperties(data, err) {
// NOTE err.name and err.message are not enumerable properties
data.name = err.name;
data.message = err.message;
for (var p in err) {
if ((p in data)) continue;
data[p] = err[p];
}
// NOTE err.stack is not an enumerable property
// stack is appended last to ensure order is the same for response
data.stack = err.stack;
}

View File

@ -191,6 +191,7 @@ describe('strong-error-handler', function() {
context('JSON response', function() { context('JSON response', function() {
it('contains all error properties when debug=true', function(done) { it('contains all error properties when debug=true', function(done) {
var error = new ErrorWithProps({ var error = new ErrorWithProps({
message: 'a test error message',
details: 'some details', details: 'some details',
extra: 'sensitive data', extra: 'sensitive data',
}); });
@ -199,15 +200,36 @@ describe('strong-error-handler', function() {
requestJson().end(function(err, res) { requestJson().end(function(err, res) {
if (err) return done(err); if (err) return done(err);
var expectedData = {statusCode: 500, stack: error.stack}; var expectedData = {
for (var key in error) expectedData[key] = error[key]; statusCode: 500,
message: 'a test error message',
name: 'ErrorWithProps',
details: 'some details',
extra: 'sensitive data',
stack: error.stack,
};
expect(res.body).to.have.property('error'); expect(res.body).to.have.property('error');
expect(res.body.error).to.eql(expectedData); expect(res.body.error).to.eql(expectedData);
done(); done();
}); });
}); });
it('contains non-enumerable Error properties when debug=true',
function(done) {
var error = new Error('a test error message');
givenErrorHandlerForError(error, {debug: true});
requestJson().end(function(err, res) {
if (err) return done(err);
expect(res.body).to.have.property('error');
var resError = res.body.error;
expect(resError).to.have.property('name', 'Error');
expect(resError).to.have.property('message',
'a test error message');
expect(resError).to.have.property('stack', error.stack);
done();
});
});
it('contains subset of properties when status=4xx', function(done) { it('contains subset of properties when status=4xx', function(done) {
var error = new ErrorWithProps({ var error = new ErrorWithProps({
name: 'ValidationError', name: 'ValidationError',