mirror of
https://github.com/feathersjs/feathers.git
synced 2026-01-25 15:23:13 +00:00
107 lines
3.2 KiB
JavaScript
107 lines
3.2 KiB
JavaScript
const path = require('path');
|
|
const errors = require('./index');
|
|
|
|
const defaults = {
|
|
public: path.resolve(__dirname, 'public'),
|
|
logger: console
|
|
};
|
|
const defaultHtmlError = path.resolve(defaults.public, 'default.html');
|
|
|
|
module.exports = function (options = {}) {
|
|
options = Object.assign({}, defaults, options);
|
|
|
|
if (typeof options.html === 'undefined') {
|
|
options.html = {
|
|
401: path.resolve(options.public, '401.html'),
|
|
404: path.resolve(options.public, '404.html'),
|
|
default: defaultHtmlError
|
|
};
|
|
}
|
|
|
|
if (typeof options.json === 'undefined') {
|
|
options.json = {};
|
|
}
|
|
|
|
return function (error, req, res, next) {
|
|
// Log the error if it didn't come from a service method call
|
|
if (options.logger && typeof options.logger.error === 'function' && !res.hook) {
|
|
options.logger.error(error);
|
|
}
|
|
|
|
if (error.type !== 'FeathersError') {
|
|
let oldError = error;
|
|
error = new errors.GeneralError(oldError.message, {
|
|
errors: oldError.errors
|
|
});
|
|
|
|
if (oldError.stack) {
|
|
error.stack = oldError.stack;
|
|
}
|
|
}
|
|
|
|
error.code = !isNaN(parseInt(error.code, 10)) ? parseInt(error.code, 10) : 500;
|
|
const formatter = {};
|
|
|
|
// If the developer passed a custom function for ALL html errors
|
|
if (typeof options.html === 'function') {
|
|
formatter['text/html'] = options.html;
|
|
} else {
|
|
let file = options.html[error.code];
|
|
if (!file) {
|
|
file = options.html.default || defaultHtmlError;
|
|
}
|
|
// If the developer passed a custom function for individual html errors
|
|
if (typeof file === 'function') {
|
|
formatter['text/html'] = file;
|
|
} else {
|
|
formatter['text/html'] = function () {
|
|
res.set('Content-Type', 'text/html');
|
|
res.sendFile(file);
|
|
};
|
|
}
|
|
}
|
|
|
|
// If the developer passed a custom function for ALL json errors
|
|
if (typeof options.json === 'function') {
|
|
formatter['application/json'] = options.json;
|
|
} else {
|
|
let handler = options.json[error.code] || options.json.default;
|
|
// If the developer passed a custom function for individual json errors
|
|
if (typeof handler === 'function') {
|
|
formatter['application/json'] = handler;
|
|
} else {
|
|
// Don't show stack trace if it is a 404 error
|
|
if (error.code === 404) {
|
|
error.stack = null;
|
|
}
|
|
|
|
formatter['application/json'] = function () {
|
|
let output = Object.assign({}, error.toJSON());
|
|
|
|
if (process.env.NODE_ENV === 'production') {
|
|
delete output.stack;
|
|
}
|
|
|
|
res.set('Content-Type', 'application/json');
|
|
res.json(output);
|
|
};
|
|
}
|
|
}
|
|
|
|
res.status(error.code);
|
|
|
|
const contentType = req.headers['content-type'] || '';
|
|
const accepts = req.headers.accept || '';
|
|
|
|
// by default just send back json
|
|
if (contentType.indexOf('json') !== -1 || accepts.indexOf('json') !== -1) {
|
|
formatter['application/json'](error, req, res, next);
|
|
} else if (options.html && (contentType.indexOf('html') !== -1 || accepts.indexOf('html') !== -1)) {
|
|
formatter['text/html'](error, req, res, next);
|
|
} else {
|
|
// TODO (EK): Maybe just return plain text
|
|
formatter['application/json'](error, req, res, next);
|
|
}
|
|
};
|
|
};
|