-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
165 lines (165 loc) · 5.51 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const cors_1 = __importDefault(require("cors"));
const path_1 = __importDefault(require("path"));
const cookie_parser_1 = __importDefault(require("cookie-parser"));
const morgan_1 = __importDefault(require("morgan"));
const swagger_ui_express_1 = __importDefault(require("swagger-ui-express"));
// @ts-ignore
const swagger_output_json_1 = __importDefault(require("./swagger_output.json"));
const index_1 = __importDefault(require("./routes/index"));
const app = (0, express_1.default)();
require("./connections/mongoDB");
app.use((0, cors_1.default)());
app.use((0, morgan_1.default)('dev'));
app.use(express_1.default.json());
app.use(express_1.default.urlencoded({ extended: false }));
app.use((0, cookie_parser_1.default)());
app.use(express_1.default.static(path_1.default.join(__dirname, 'public')));
app.use('/api/doc', swagger_ui_express_1.default.serve, swagger_ui_express_1.default.setup(swagger_output_json_1.default, { customCssUrl: '/swagger-ui.css' }));
process.on('uncaughtException', err => {
// 記錄錯誤下來,等到服務都處理完後,停掉該 process
console.error('Uncaughted Exception!');
console.error(err);
process.exit(1);
});
/**
* Swagger-Autogen properties-inheritance
* https://github.com/davibaltar/swagger-autogen#properties-inheritance
*/
app.use('/api',
/*
#swagger.security = [{ "bearerAuth": [] }]
#swagger.responses[400] = {
description: '一般錯誤訊息',
content: {
"application/json": {
schema: { $ref: '#/definitions/ResponseErrorMsg' }
}
}
}
#swagger.responses[401] = {
description: 'token 無效',
content: {
"application/json": {
schema: { $ref: '#/definitions/ResponseInvalidToken' }
}
}
}
#swagger.responses[404] = {
description: '無此路由',
content: {
"application/json": {
schema: { $ref: '#/definitions/ResponseNotFoundPage' }
}
}
}
#swagger.responses[500] = {
description: '重大錯誤,請後端查 log',
content: {
"application/json": {
schema: { $ref: '#/definitions/ResponseServerErrorMsg' }
}
}
}
#swagger.responses[504] = {
description: '伺服器繁忙中,請稍後在操作'
}
*/
index_1.default);
app.use((req, res, next) => {
const error = new Error('無此路由');
error.statusCode = 404;
error.isOperational = true;
next(error);
});
const resErrorProd = (err, res) => {
if (err.isOperational) {
if (err.columns) {
return res.status(err.statusCode).send({
result: false,
msg: err.message,
columns: err.errors,
});
}
return res.status(err.statusCode).send({
result: false,
msg: err.message,
});
}
console.log('重大錯誤 => ', err);
/**
* Vercel
* https://vercel.com/guides/using-express-with-vercel#standalone-express
*
* Notice that we added a setHeader line for our Cache-Control. This describes the lifetime of our resource, telling the CDN to serve from the cache and update in the background (at most once per second).
*/
res.setHeader('Cache-Control', 's-max-age=1, stale-while-revalidate');
res.status(err.statusCode).send({
result: false,
msg: '系統錯誤,請洽系統管理員',
});
};
const resErrorDev = (err, res) => {
res.status(err.statusCode).send({
result: false,
name: err.name,
message: err.message,
stack: err.stack,
error: err,
});
};
app.use((err, req, res, next) => {
err.statusCode = err.statusCode || 500;
if (err.message.indexOf('圖片檔案格式') !== -1) {
err.statusCode = 400;
err.isOperational = true;
}
if (process.env.NODE_ENV === 'development') {
return resErrorDev(err, res);
}
if (err.name === 'ValidationError') {
err.statusCode = 400;
err.columns = err.errors;
err.isOperational = true;
return resErrorProd(err, res);
}
if (err.name === 'JsonWebTokenError' || err.name === 'TokenExpiredError') {
err.message = '請重新登入帳號';
err.statusCode = 401;
err.isOperational = true;
return resErrorProd(err, res);
}
if (err.name === 'MulterError') {
err.statusCode = 400;
err.isOperational = true;
return resErrorProd(err, res);
}
if (err.name === 'TypeError') {
err.statusCode = 400;
err.isOperational = true;
return resErrorProd(err, res);
}
if (err.name === 'CastError') {
err.message = '傳入的值與伺服器定義型別有誤';
err.statusCode = 400;
err.isOperational = true;
return resErrorProd(err, res);
}
if (err.name === 'SyntaxError') {
err.message = err.message;
err.statusCode = 400;
err.isOperational = true;
return resErrorProd(err, res);
}
resErrorProd(err, res);
});
process.on('unhandledRejection', (err, promise) => {
console.error('未捕捉到的 rejection:', promise);
console.error('unhandledRejection 原因:', err);
});
exports.default = app;