2016-05-11 11:53:28 +00:00
|
|
|
// Copyright IBM Corp. 2016. All Rights Reserved.
|
|
|
|
// Node module: strong-error-handler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2016-05-20 23:15:14 +00:00
|
|
|
var cloneAllProperties = require('../lib/clone.js');
|
2016-05-11 11:53:28 +00:00
|
|
|
var httpStatus = require('http-status');
|
|
|
|
|
2017-01-30 03:59:35 +00:00
|
|
|
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;
|
|
|
|
|
2016-05-11 11:53:28 +00:00
|
|
|
if (Array.isArray(err) && isDebugMode) {
|
|
|
|
err = serializeArrayOfErrors(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
var data = Object.create(null);
|
|
|
|
fillStatusCode(data, err);
|
|
|
|
|
|
|
|
if (typeof err !== 'object') {
|
2016-05-16 14:57:15 +00:00
|
|
|
err = {
|
|
|
|
statusCode: 500,
|
|
|
|
message: '' + err,
|
|
|
|
};
|
2016-05-11 11:53:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isDebugMode) {
|
|
|
|
fillDebugData(data, err);
|
|
|
|
} else if (data.statusCode >= 400 && data.statusCode <= 499) {
|
|
|
|
fillBadRequestError(data, err);
|
|
|
|
} else {
|
|
|
|
fillInternalError(data, err);
|
|
|
|
}
|
|
|
|
|
2017-01-30 13:48:38 +00:00
|
|
|
var safeFields = options.safeFields || [];
|
|
|
|
fillSafeFields(data, err, safeFields);
|
2017-01-30 03:59:35 +00:00
|
|
|
|
2016-05-11 11:53:28 +00:00
|
|
|
return data;
|
|
|
|
};
|
|
|
|
|
|
|
|
function serializeArrayOfErrors(errors) {
|
|
|
|
var details = [];
|
|
|
|
for (var ix in errors) {
|
|
|
|
var err = errors[ix];
|
|
|
|
if (typeof err !== 'object') {
|
|
|
|
details.push('' + err);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-05-16 14:57:15 +00:00
|
|
|
var data = {};
|
|
|
|
cloneAllProperties(data, err);
|
2016-05-20 23:15:14 +00:00
|
|
|
delete data.statusCode;
|
2016-05-11 11:53:28 +00:00
|
|
|
details.push(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
name: 'ArrayOfErrors',
|
|
|
|
message: 'Failed with multiple errors, ' +
|
|
|
|
'see `details` for more information.',
|
|
|
|
details: details,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function fillStatusCode(data, err) {
|
|
|
|
data.statusCode = err.statusCode || err.status;
|
|
|
|
if (!data.statusCode || data.statusCode < 400)
|
|
|
|
data.statusCode = 500;
|
|
|
|
}
|
|
|
|
|
|
|
|
function fillDebugData(data, err) {
|
2016-05-16 14:57:15 +00:00
|
|
|
cloneAllProperties(data, err);
|
2016-05-11 11:53:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function fillBadRequestError(data, err) {
|
|
|
|
data.name = err.name;
|
|
|
|
data.message = err.message;
|
2017-01-30 10:44:35 +00:00
|
|
|
data.code = err.code;
|
2016-05-11 11:53:28 +00:00
|
|
|
data.details = err.details;
|
|
|
|
}
|
|
|
|
|
|
|
|
function fillInternalError(data, err) {
|
|
|
|
data.message = httpStatus[data.statusCode] || 'Unknown Error';
|
|
|
|
}
|
2017-01-30 03:59:35 +00:00
|
|
|
|
|
|
|
function fillSafeFields(data, err, safeFields) {
|
|
|
|
if (!Array.isArray(safeFields)) {
|
|
|
|
safeFields = [safeFields];
|
|
|
|
}
|
|
|
|
|
|
|
|
safeFields.forEach(function(field) {
|
2018-03-05 03:39:51 +00:00
|
|
|
if (err[field] !== undefined) {
|
|
|
|
data[field] = err[field];
|
|
|
|
}
|
2017-01-30 03:59:35 +00:00
|
|
|
});
|
|
|
|
}
|