1 | const errors = require('@feathersjs/errors');
|
2 | const path = require('path');
|
3 |
|
4 | const defaults = {
|
5 | public: path.resolve(__dirname, 'public'),
|
6 | logger: console
|
7 | };
|
8 | const defaultHtmlError = path.resolve(defaults.public, 'default.html');
|
9 |
|
10 | module.exports = function (options = {}) {
|
11 | options = Object.assign({}, defaults, options);
|
12 |
|
13 | if (typeof options.html === 'undefined') {
|
14 | options.html = {
|
15 | 401: path.resolve(options.public, '401.html'),
|
16 | 404: path.resolve(options.public, '404.html'),
|
17 | default: defaultHtmlError
|
18 | };
|
19 | }
|
20 |
|
21 | if (typeof options.json === 'undefined') {
|
22 | options.json = {};
|
23 | }
|
24 |
|
25 | return function (error, req, res, next) {
|
26 |
|
27 | error.code = !isNaN(parseInt(error.code, 10)) ? parseInt(error.code, 10) : 500;
|
28 |
|
29 |
|
30 | if (options.logger && typeof options.logger.error === 'function' && !res.hook) {
|
31 | if (error.code >= 500) {
|
32 | options.logger.error(error);
|
33 | } else {
|
34 | options.logger.info(error);
|
35 | }
|
36 | }
|
37 |
|
38 | if (error.type !== 'FeathersError') {
|
39 | let oldError = error;
|
40 | error = new errors.GeneralError(oldError.message, {
|
41 | errors: oldError.errors
|
42 | });
|
43 |
|
44 | if (oldError.stack) {
|
45 | error.stack = oldError.stack;
|
46 | }
|
47 | }
|
48 |
|
49 | const formatter = {};
|
50 |
|
51 |
|
52 | if (typeof options.html === 'function') {
|
53 | formatter['text/html'] = options.html;
|
54 | } else {
|
55 | let file = options.html[error.code];
|
56 | if (!file) {
|
57 | file = options.html.default || defaultHtmlError;
|
58 | }
|
59 |
|
60 | if (typeof file === 'function') {
|
61 | formatter['text/html'] = file;
|
62 | } else {
|
63 | formatter['text/html'] = function () {
|
64 | res.set('Content-Type', 'text/html');
|
65 | res.sendFile(file);
|
66 | };
|
67 | }
|
68 | }
|
69 |
|
70 |
|
71 | if (typeof options.json === 'function') {
|
72 | formatter['application/json'] = options.json;
|
73 | } else {
|
74 | let handler = options.json[error.code] || options.json.default;
|
75 |
|
76 | if (typeof handler === 'function') {
|
77 | formatter['application/json'] = handler;
|
78 | } else {
|
79 |
|
80 | if (error.code === 404) {
|
81 | error.stack = null;
|
82 | }
|
83 |
|
84 | formatter['application/json'] = function () {
|
85 | let output = Object.assign({}, error.toJSON());
|
86 |
|
87 | if (process.env.NODE_ENV === 'production') {
|
88 | delete output.stack;
|
89 | }
|
90 |
|
91 | res.set('Content-Type', 'application/json');
|
92 | res.json(output);
|
93 | };
|
94 | }
|
95 | }
|
96 |
|
97 | res.status(error.code);
|
98 |
|
99 | const contentType = req.headers['content-type'] || '';
|
100 | const accepts = req.headers.accept || '';
|
101 |
|
102 |
|
103 | if (contentType.indexOf('json') !== -1 || accepts.indexOf('json') !== -1) {
|
104 | formatter['application/json'](error, req, res, next);
|
105 | } else if (options.html && (contentType.indexOf('html') !== -1 || accepts.indexOf('html') !== -1)) {
|
106 | formatter['text/html'](error, req, res, next);
|
107 | } else {
|
108 |
|
109 | formatter['application/json'](error, req, res, next);
|
110 | }
|
111 | };
|
112 | };
|