Files
NodeBB/src/controllers/errors.js

100 lines
3.0 KiB
JavaScript
Raw Normal View History

2017-03-02 14:57:33 +03:00
'use strict';
2021-02-04 00:06:15 -07:00
const nconf = require('nconf');
const winston = require('winston');
const validator = require('validator');
const translator = require('../translator');
2021-02-04 00:06:15 -07:00
const plugins = require('../plugins');
const middleware = require('../middleware');
const middlewareHelpers = require('../middleware/helpers');
const helpers = require('./helpers');
2017-03-02 14:57:33 +03:00
exports.handleURIErrors = async function handleURIErrors(err, req, res, next) {
2017-03-02 14:57:33 +03:00
// Handle cases where malformed URIs are passed in
if (err instanceof URIError) {
2021-02-03 23:59:08 -07:00
const cleanPath = req.path.replace(new RegExp(`^${nconf.get('relative_path')}`), '');
2021-02-04 00:06:15 -07:00
const tidMatch = cleanPath.match(/^\/topic\/(\d+)\//);
const cidMatch = cleanPath.match(/^\/category\/(\d+)\//);
2017-03-02 14:57:33 +03:00
if (tidMatch) {
res.redirect(nconf.get('relative_path') + tidMatch[0]);
} else if (cidMatch) {
res.redirect(nconf.get('relative_path') + cidMatch[0]);
} else {
2021-02-03 23:59:08 -07:00
winston.warn(`[controller] Bad request: ${req.path}`);
if (req.path.startsWith(`${nconf.get('relative_path')}/api`)) {
2017-03-02 14:57:33 +03:00
res.status(400).json({
error: '[[global:400.title]]',
});
} else {
await middleware.buildHeaderAsync(req, res);
res.status(400).render('400', { error: validator.escape(String(err.message)) });
2017-03-02 14:57:33 +03:00
}
}
} else {
next(err);
}
};
// this needs to have four arguments or express treats it as `(req, res, next)`
// don't remove `next`!
2018-12-17 16:56:38 -05:00
exports.handleErrors = function handleErrors(err, req, res, next) { // eslint-disable-line no-unused-vars
2021-02-04 00:06:15 -07:00
const cases = {
2017-09-12 13:46:51 -04:00
EBADCSRFTOKEN: function () {
2021-02-03 23:59:08 -07:00
winston.error(`${req.path}\n${err.message}`);
2017-09-12 13:46:51 -04:00
res.sendStatus(403);
},
'blacklisted-ip': function () {
res.status(403).type('text/plain').send(err.message);
},
};
2021-02-04 00:06:15 -07:00
const defaultHandler = async function () {
2017-09-12 13:46:51 -04:00
// Display NodeBB error page
2021-02-04 00:06:15 -07:00
const status = parseInt(err.status, 10);
2017-09-12 13:46:51 -04:00
if ((status === 302 || status === 308) && err.path) {
return res.locals.isAPI ? res.set('X-Redirect', err.path).status(200).json(err.path) : res.redirect(nconf.get('relative_path') + err.path);
2017-09-12 13:46:51 -04:00
}
2017-03-02 14:57:33 +03:00
const path = String(req.path || '');
2017-03-02 14:57:33 +03:00
if (path.startsWith(`${nconf.get('relative_path')}/api/v3`)) {
let status = 500;
if (err.message.startsWith('[[')) {
status = 400;
err.message = await translator.translate(err.message);
}
return helpers.formatApiResponse(status, res, err);
}
2017-03-02 14:57:33 +03:00
winston.error(`${req.path}\n${err.stack}`);
res.status(status || 500);
2021-06-18 09:55:08 -04:00
const data = {
path: validator.escape(path),
error: validator.escape(String(err.message)),
bodyClass: middlewareHelpers.buildBodyClass(req, res),
2021-06-18 09:55:08 -04:00
};
2017-09-12 13:46:51 -04:00
if (res.locals.isAPI) {
2021-06-18 09:55:08 -04:00
res.json(data);
2017-09-12 13:46:51 -04:00
} else {
await middleware.buildHeaderAsync(req, res);
2021-06-18 09:55:08 -04:00
res.render('500', data);
2017-09-12 13:46:51 -04:00
}
};
2017-03-02 14:57:33 +03:00
plugins.hooks.fire('filter:error.handle', {
2017-09-12 13:46:51 -04:00
cases: cases,
2021-02-04 00:01:39 -07:00
}, (_err, data) => {
2017-09-12 13:46:51 -04:00
if (_err) {
// Assume defaults
2021-02-03 23:59:08 -07:00
winston.warn(`[errors/handle] Unable to retrieve plugin handlers for errors: ${_err.message}`);
2017-09-12 13:46:51 -04:00
data.cases = cases;
}
if (data.cases.hasOwnProperty(err.code)) {
data.cases[err.code](err, req, res, defaultHandler);
2017-09-12 13:46:51 -04:00
} else {
defaultHandler();
}
});
2017-03-02 14:57:33 +03:00
};