1 | 'use strict';
|
2 |
|
3 | const { pick } = require('lodash');
|
4 | const AppError = require('./appError');
|
5 | const log = require('./models/log').module('API');
|
6 |
|
7 | const errorHandler = {
|
8 |
|
9 | |
10 |
|
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 |
|
88 | module.exports = errorHandler;
|