UNPKG

2.55 kBJavaScriptView Raw
1'use strict';
2
3const { pick } = require('lodash');
4const AppError = require('./appError');
5const log = require('./models/log').module('API');
6
7const errorHandler = {
8
9 /**
10 * @returns {Function}
11 */
12 getErrorHandler () {
13
14 return async function (ctx, next) {
15
16 try {
17
18 await next();
19
20 } catch (originalError) {
21
22 let err = originalError;
23
24 if (!(err instanceof AppError)) {
25
26 if (err instanceof Error) {
27 const redirect = err.redirect || null;
28 err = new AppError(`${err.name}: ${err.message}`, 500, 500);
29 err.redirect = redirect;
30
31 } else if (typeof err === 'string') {
32 err = new AppError(err, 500, 500);
33
34 } else {
35 err = new AppError('Unknown error', 500, 500);
36 }
37
38 err.stack = originalError.stack;
39 }
40
41 const metaData = {
42 code: err.code,
43 httpStatus: err.httpStatus || 500,
44 url: ctx.request.originalUrl,
45 query: ctx.request.query,
46 method: ctx.req.method,
47 remoteAddress: ctx.req.headers['x-forwarded-for'] || ctx.req.connection.remoteAddress
48 };
49
50 if (!ctx.request.is('multipart/*')) {
51 metaData.body = ctx.request.body;
52 }
53
54 if (ctx.req.headers && ctx.req.headers.referer) {
55 metaData.referer = ctx.req.headers.referer;
56 }
57
58 if (err.redirect) {
59 metaData.redirect = err.redirect;
60 }
61
62 if (err.forceLogLevel) {
63 metaData.forceLogLevel = err.forceLogLevel;
64 }
65
66 if (err.httpStatus === 404 || err.httpStatus === 401 || err.httpStatus === 429) {
67 log.warn(err, metaData);
68
69 } else if (err.httpStatus === 500 || err.httpStatus === 408) {
70 log.error(err, metaData);
71
72 } else {
73 metaData.response = err;
74 log.info(err, metaData);
75 }
76
77 ctx.status = err.httpStatus;
78 ctx.body = { code: err.code, message: err.message, ...pick(err.meta, err.publicFields || []) };
79
80 }
81
82 };
83
84 }
85
86};
87
88module.exports = errorHandler;