1 | const path = require('path')
|
2 | const template = require('lodash/template')
|
3 | const fs = require('fs')
|
4 |
|
5 | let templates = {
|
6 | 403: template(fs.readFileSync(path.join(__dirname, 'views/403.html'))),
|
7 | 404: template(fs.readFileSync(path.join(__dirname, 'views/404.html'))),
|
8 | 500: template(fs.readFileSync(path.join(__dirname, 'views/500.html')))
|
9 | }
|
10 |
|
11 |
|
12 |
|
13 | const readFilesFromDir = dirPath => {
|
14 | fs.readdirSync(dirPath).forEach(file => {
|
15 | const fileName = file.split('.').shift()
|
16 |
|
17 | if (Number.isNaN(fileName)) return null
|
18 | const fileContent = template(fs.readFileSync(path.join(dirPath, file)))
|
19 | templates[fileName] = fileContent
|
20 | })
|
21 | }
|
22 |
|
23 | module.exports = (options = {}) => {
|
24 | if (options.errorPagesPath) {
|
25 | readFilesFromDir(path.join(options.dirname, options.errorPagesPath))
|
26 | }
|
27 |
|
28 | return (err, req, res, next) => {
|
29 | console.log(err.stack ? err.stack : err)
|
30 |
|
31 | if ((err.name === 'MongoError') && (err.message === 'no primary server available')) {
|
32 | setTimeout(() => {
|
33 | console.log("EXIT because of 'no primary server available'")
|
34 | process.exit()
|
35 | }, 1000)
|
36 | }
|
37 |
|
38 |
|
39 | let message = err.message || err.toString()
|
40 | let status = parseInt(message)
|
41 | status = (status >= 400 && status < 600) ? status : 500
|
42 |
|
43 | if (status === 403 || status === 404 || status === 500) {
|
44 | if (status === 403 && !req.session.loggedIn) {
|
45 | res.cookie('redirectWhen', 'loggedIn', { maxAge: 1000 * 3600 })
|
46 | res.cookie('redirect', req.url, { maxAge: 1000 * 3600 })
|
47 | res.redirect(options.loginUrl || '/')
|
48 | } else {
|
49 | res.status(status).send(templates[status]({
|
50 | url: req.url
|
51 | }))
|
52 | }
|
53 | } else {
|
54 | if (!res.finished) res.sendStatus(status)
|
55 | }
|
56 | }
|
57 | }
|