diff --git a/controllers/errorsController.js b/controllers/errorsController.js new file mode 100644 index 0000000..7ed9570 --- /dev/null +++ b/controllers/errorsController.js @@ -0,0 +1,66 @@ +const path = require('path') +const paths = require('./pathsController') +const ClientError = require('./utils/ClientError') +const ServerError = require('./utils/ServerError') +const config = require('./../config') +const logger = require('./../logger') + +const self = { + errorPagesCodes: Object.keys(config.errorPages) + .filter(key => /^\d+$/.test(key)) + .map(key => Number(key)) +} + +self.handle = (error, req, res, next) => { + if (!res || res.headersSent) { + console.error('Unexpected missing "res" object or headers alredy sent.') + return console.trace() + } + + // Error messages that can be returned to users + const isClientError = error instanceof ClientError + const isServerError = error instanceof ServerError + + const logStack = (!isClientError && !isServerError) || + (isServerError && error.logStack) + if (logStack) { + logger.error(error) + } + + const statusCode = (isClientError || isServerError) + ? error.statusCode + : 500 + + const json = {} + + const description = (isClientError || isServerError) + ? error.message + : 'An unexpected error occurred. Try again?' + if (description) { + json.description = description + } + + if ((isClientError || isServerError) && error.code) { + json.code = error.code + } + + res.setHeader('Cache-Control', 'no-store') + + if (Object.keys(json).length) { + json.success = false + return res.status(statusCode).json(json) + } else { + if (self.errorPagesCodes.includes(statusCode)) { + return res.status(statusCode).sendFile(path.join(paths.errorRoot, config.errorPages[statusCode])) + } else { + return res.status(statusCode).end() + } + } +} + +self.handleMissing = (req, res, next) => { + res.setHeader('Cache-Control', 'no-store') + return res.status(404).sendFile(path.join(paths.errorRoot, config.errorPages[404])) +} + +module.exports = self diff --git a/lolisafe.js b/lolisafe.js index ec73249..80b09ac 100644 --- a/lolisafe.js +++ b/lolisafe.js @@ -40,6 +40,7 @@ const versions = require('./src/versions') logger.log('Starting lolisafe\u2026') const safe = express() +const errors = require('./controllers/errorsController') const paths = require('./controllers/pathsController') paths.initSync() const utils = require('./controllers/utilsController') @@ -317,21 +318,9 @@ safe.use('/api', api) } } - // Error pages - safe.use((req, res, next) => { - if (!res.headersSent) { - res.setHeader('Cache-Control', 'no-store') - res.status(404).sendFile(path.join(paths.errorRoot, config.errorPages[404])) - } - }) - - safe.use((error, req, res, next) => { - logger.error(error) - if (!res.headersSent) { - res.setHeader('Cache-Control', 'no-store') - res.status(500).sendFile(path.join(paths.errorRoot, config.errorPages[500])) - } - }) + // Express error handlers + safe.use(errors.handleMissing) + safe.use(errors.handle) // Git hash if (config.showGitHash) {