Allow safeFields to work with arrays
Co-authored-by: Miroslav Bajtos <mbajtoss@gmail.com>
This commit is contained in:
parent
a431cf54fa
commit
7828534804
|
@ -8,16 +8,18 @@
|
||||||
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, options) {
|
module.exports = buildResponseData;
|
||||||
|
|
||||||
|
function buildResponseData(err, options) {
|
||||||
// Debugging mode is disabled by default. When turned on (in dev),
|
// Debugging mode is disabled by default. When turned on (in dev),
|
||||||
// all error properties (including) stack traces are sent in the response
|
// all error properties (including) stack traces are sent in the response
|
||||||
var isDebugMode = options.debug;
|
const isDebugMode = options.debug;
|
||||||
|
|
||||||
if (Array.isArray(err) && isDebugMode) {
|
if (Array.isArray(err)) {
|
||||||
err = serializeArrayOfErrors(err);
|
return serializeArrayOfErrors(err, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = Object.create(null);
|
const data = Object.create(null);
|
||||||
fillStatusCode(data, err);
|
fillStatusCode(data, err);
|
||||||
|
|
||||||
if (typeof err !== 'object') {
|
if (typeof err !== 'object') {
|
||||||
|
@ -29,35 +31,25 @@ module.exports = function buildResponseData(err, options) {
|
||||||
|
|
||||||
if (isDebugMode) {
|
if (isDebugMode) {
|
||||||
fillDebugData(data, err);
|
fillDebugData(data, err);
|
||||||
} else if (data.statusCode >= 400 && data.statusCode <= 499) {
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.statusCode >= 400 && data.statusCode <= 499) {
|
||||||
fillBadRequestError(data, err);
|
fillBadRequestError(data, err);
|
||||||
} else {
|
} else {
|
||||||
fillInternalError(data, err);
|
fillInternalError(data, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var safeFields = options.safeFields || [];
|
const safeFields = options.safeFields || [];
|
||||||
fillSafeFields(data, err, safeFields);
|
fillSafeFields(data, err, safeFields);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
function serializeArrayOfErrors(errors) {
|
function serializeArrayOfErrors(errors, options) {
|
||||||
var details = [];
|
const details = errors.map(e => buildResponseData(e, options));
|
||||||
for (var ix in errors) {
|
|
||||||
var err = errors[ix];
|
|
||||||
if (typeof err !== 'object') {
|
|
||||||
details.push('' + err);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = {};
|
|
||||||
cloneAllProperties(data, err);
|
|
||||||
delete data.statusCode;
|
|
||||||
details.push(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: 'ArrayOfErrors',
|
statusCode: 500,
|
||||||
message: 'Failed with multiple errors, ' +
|
message: 'Failed with multiple errors, ' +
|
||||||
'see `details` for more information.',
|
'see `details` for more information.',
|
||||||
details: details,
|
details: details,
|
||||||
|
|
|
@ -397,48 +397,101 @@ describe('strong-error-handler', function() {
|
||||||
|
|
||||||
requestJson().expect(500).end(function(err, res) {
|
requestJson().expect(500).end(function(err, res) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(res.body).to.eql({
|
const data = res.body.error;
|
||||||
error: {
|
expect(data).to.have.property('message').that.match(/multiple errors/);
|
||||||
statusCode: 500,
|
expect(data).to.have.property('details').eql([
|
||||||
message: 'Internal Server Error',
|
{statusCode: 500, message: 'Internal Server Error'},
|
||||||
},
|
{statusCode: 500, message: 'Internal Server Error'},
|
||||||
});
|
{statusCode: 500, message: 'Internal Server Error'},
|
||||||
|
]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns all array items when debug=true', function(done) {
|
it('returns all array items when debug=true', function(done) {
|
||||||
var testError = new ErrorWithProps({
|
const testError = new ErrorWithProps({
|
||||||
message: 'expected test error',
|
message: 'expected test error',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
});
|
});
|
||||||
var anotherError = new ErrorWithProps({
|
const anotherError = new ErrorWithProps({
|
||||||
message: 'another expected error',
|
message: 'another expected error',
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
});
|
});
|
||||||
var errors = [testError, anotherError, 'ERR STRING'];
|
const errors = [testError, anotherError, 'ERR STRING'];
|
||||||
givenErrorHandlerForError(errors, {debug: true});
|
givenErrorHandlerForError(errors, {debug: true});
|
||||||
|
|
||||||
requestJson().expect(500).end(function(err, res) {
|
requestJson().expect(500).end(function(err, res) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
var data = res.body.error;
|
const data = res.body.error;
|
||||||
expect(data).to.have.property('message').that.match(/multiple errors/);
|
expect(data).to.have.property('message').that.match(/multiple errors/);
|
||||||
var expectTestError = getExpectedErrorData(testError);
|
|
||||||
delete expectTestError.statusCode;
|
|
||||||
var expectAnotherError = getExpectedErrorData(anotherError);
|
|
||||||
delete expectAnotherError.statusCode;
|
|
||||||
|
|
||||||
var expectedDetails = [
|
const expectedDetails = [
|
||||||
expectTestError,
|
getExpectedErrorData(testError),
|
||||||
expectAnotherError,
|
getExpectedErrorData(anotherError),
|
||||||
'ERR STRING',
|
{message: 'ERR STRING', statusCode: 500},
|
||||||
];
|
];
|
||||||
expect(data).to.have.property('details').to.eql(expectedDetails);
|
expect(data).to.have.property('details').to.eql(expectedDetails);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('includes safeFields of array items when debug=false', (done) => {
|
||||||
|
const internalError = new ErrorWithProps({
|
||||||
|
message: 'a test error message',
|
||||||
|
code: 'MACHINE_READABLE_CODE',
|
||||||
|
details: 'some details',
|
||||||
|
extra: 'sensitive data',
|
||||||
|
});
|
||||||
|
const validationError = new ErrorWithProps({
|
||||||
|
name: 'ValidationError',
|
||||||
|
message: 'The model instance is not valid.',
|
||||||
|
statusCode: 422,
|
||||||
|
code: 'VALIDATION_ERROR',
|
||||||
|
details: 'some details',
|
||||||
|
extra: 'sensitive data',
|
||||||
|
});
|
||||||
|
|
||||||
|
const errors = [internalError, validationError, 'ERR STRING'];
|
||||||
|
givenErrorHandlerForError(errors, {
|
||||||
|
debug: false,
|
||||||
|
safeFields: ['code'],
|
||||||
|
});
|
||||||
|
|
||||||
|
requestJson().end(function(err, res) {
|
||||||
|
if (err) return done(err);
|
||||||
|
const data = res.body.error;
|
||||||
|
|
||||||
|
const expectedInternalError = {
|
||||||
|
statusCode: 500,
|
||||||
|
message: 'Internal Server Error',
|
||||||
|
code: 'MACHINE_READABLE_CODE',
|
||||||
|
// notice the property "extra" is not included
|
||||||
|
};
|
||||||
|
const expectedValidationError = {
|
||||||
|
statusCode: 422,
|
||||||
|
message: 'The model instance is not valid.',
|
||||||
|
name: 'ValidationError',
|
||||||
|
code: 'VALIDATION_ERROR',
|
||||||
|
details: 'some details',
|
||||||
|
// notice the property "extra" is not included
|
||||||
|
};
|
||||||
|
const expectedErrorFromString = {
|
||||||
|
message: 'Internal Server Error',
|
||||||
|
statusCode: 500,
|
||||||
|
};
|
||||||
|
const expectedDetails = [
|
||||||
|
expectedInternalError,
|
||||||
|
expectedValidationError,
|
||||||
|
expectedErrorFromString,
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(data).to.have.property('message').that.match(/multiple errors/);
|
||||||
|
expect(data).to.have.property('details').to.eql(expectedDetails);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('handles non-Error argument as 500 when debug=false', function(done) {
|
it('handles non-Error argument as 500 when debug=false', function(done) {
|
||||||
givenErrorHandlerForError('Error Message', {debug: false});
|
givenErrorHandlerForError('Error Message', {debug: false});
|
||||||
requestJson().expect(500).end(function(err, res) {
|
requestJson().expect(500).end(function(err, res) {
|
||||||
|
|
Loading…
Reference in New Issue