Support options.safeFields

This commit is contained in:
Zak Barbuto 2017-01-30 14:29:35 +10:30 committed by Miroslav Bajtoš
parent 9d6f07181f
commit 4e3f6eb6cc
3 changed files with 62 additions and 6 deletions

View File

@ -8,7 +8,11 @@
var cloneAllProperties = require('../lib/clone.js'); var cloneAllProperties = require('../lib/clone.js');
var httpStatus = require('http-status'); var httpStatus = require('http-status');
module.exports = function buildResponseData(err, isDebugMode) { module.exports = function buildResponseData(err, options) {
// Debugging mode is disabled by default. When turned on (in dev),
// all error properties (including) stack traces are sent in the response
var isDebugMode = options.debug;
if (Array.isArray(err) && isDebugMode) { if (Array.isArray(err) && isDebugMode) {
err = serializeArrayOfErrors(err); err = serializeArrayOfErrors(err);
} }
@ -31,6 +35,9 @@ module.exports = function buildResponseData(err, isDebugMode) {
fillInternalError(data, err); fillInternalError(data, err);
} }
options.safeFields = options.safeFields || [];
fillSafeFields(data, err, options.safeFields);
return data; return data;
}; };
@ -76,3 +83,13 @@ 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 fillSafeFields(data, err, safeFields) {
if (!Array.isArray(safeFields)) {
safeFields = [safeFields];
}
safeFields.forEach(function(field) {
data[field] = err[field];
});
}

View File

@ -28,10 +28,6 @@ exports = module.exports = function createStrongErrorHandler(options) {
debug('Initializing with options %j', options); debug('Initializing with options %j', options);
// Debugging mode is disabled by default. When turned on (in dev),
// all error properties (including) stack traces are sent in the response
var isDebugMode = options.debug;
// Log all errors via console.error (enabled by default) // Log all errors via console.error (enabled by default)
var logError = options.log !== false ? logToConsole : noop; var logError = options.log !== false ? logToConsole : noop;
@ -49,7 +45,7 @@ exports = module.exports = function createStrongErrorHandler(options) {
if (!err.status && !err.statusCode && res.statusCode >= 400) if (!err.status && !err.statusCode && res.statusCode >= 400)
err.statusCode = res.statusCode; err.statusCode = res.statusCode;
var data = buildResponseData(err, isDebugMode); var data = buildResponseData(err, options);
debug('Response status %s data %j', data.statusCode, data); debug('Response status %s data %j', data.statusCode, data);
res.setHeader('X-Content-Type-Options', 'nosniff'); res.setHeader('X-Content-Type-Options', 'nosniff');

View File

@ -231,6 +231,49 @@ describe('strong-error-handler', function() {
}); });
}); });
it('should allow setting safe fields when status=5xx', function(done) {
var error = new ErrorWithProps({
name: 'Error',
safeField: 'SAFE',
unsafeField: 'UNSAFE',
});
givenErrorHandlerForError(error, {
safeFields: ['safeField'],
});
requestJson().end(function(err, res) {
if (err) return done(err);
expect(res.body).to.have.property('error');
expect(res.body.error).to.have.property('safeField', 'SAFE');
expect(res.body.error).not.to.have.property('unsafeField');
done();
});
});
it('should allow setting safe fields when status=4xx', function(done) {
var error = new ErrorWithProps({
name: 'Error',
statusCode: 422,
safeField: 'SAFE',
unsafeField: 'UNSAFE',
});
givenErrorHandlerForError(error, {
safeFields: ['safeField'],
});
requestJson().end(function(err, res) {
if (err) return done(err);
expect(res.body).to.have.property('error');
expect(res.body.error).to.have.property('safeField', 'SAFE');
expect(res.body.error).not.to.have.property('unsafeField');
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',