From ce9ee62fa00201e0098195357a190a83ceb6636e Mon Sep 17 00:00:00 2001 From: Mathias Schreck Date: Tue, 16 Aug 2016 19:46:59 +0200 Subject: [PATCH] Handle callback errors --- app.js | 15 +++++++++++++++ install/web.js | 4 ++++ public/src/admin/admin.js | 2 +- public/src/admin/advanced/errors.js | 4 ++++ public/src/admin/advanced/logs.js | 2 +- public/src/admin/appearance/customise.js | 4 ++-- public/src/admin/extend/plugins.js | 3 +++ public/src/admin/general/dashboard.js | 3 +++ public/src/admin/manage/groups.js | 4 ++++ public/src/admin/manage/ip-blacklist.js | 4 ++++ public/src/admin/settings/email.js | 4 ++-- public/src/app.js | 2 +- public/src/client/category.js | 4 ++++ public/src/client/categoryTools.js | 4 ++++ public/src/client/groups/details.js | 4 ++-- public/src/client/topic.js | 3 +++ public/src/client/users.js | 4 ++++ public/src/modules/notifications.js | 4 ++++ public/src/modules/search.js | 4 ++++ public/src/modules/settings.js | 20 ++++++++++++++------ public/src/utils.js | 8 ++++++++ src/controllers/admin/categories.js | 4 ++++ src/controllers/admin/errors.js | 12 ++++++++++-- src/controllers/admin/homepage.js | 4 ++++ src/controllers/admin/settings.js | 14 +++++++++++++- src/controllers/admin/sounds.js | 4 ++++ src/controllers/admin/uploads.js | 4 ++++ src/controllers/authentication.js | 12 ++++++++++++ src/controllers/index.js | 8 ++++++++ src/groups/cover.js | 5 +++++ src/install.js | 3 +++ src/languages.js | 4 ++++ src/meta/css.js | 4 ++++ src/meta/errors.js | 4 ++++ src/meta/js.js | 4 ++++ src/meta/tags.js | 4 ++++ src/meta/themes.js | 4 ++++ src/middleware/middleware.js | 4 ++++ src/plugins.js | 12 ++++++++++-- src/plugins/install.js | 4 ++++ src/plugins/load.js | 4 ++++ src/posts/flags.js | 4 ++++ src/posts/summary.js | 4 ++++ src/reset.js | 7 ++++++- src/rewards/admin.js | 8 ++++++++ src/rewards/index.js | 10 +++++++++- src/routes/debug.js | 17 +++++++++++++++++ src/socket.io/helpers.js | 8 ++++++++ src/socket.io/user.js | 4 ++++ src/socket.io/user/picture.js | 4 ++++ src/socket.io/user/profile.js | 4 ++++ src/upgrade.js | 24 ++++++++++++++++++++++++ src/user/auth.js | 2 +- src/user/digest.js | 4 ++++ src/user/follow.js | 4 ++++ src/user/picture.js | 4 ++++ src/user/profile.js | 4 ++++ tests/categories.js | 7 +++++++ tests/database/list.js | 2 ++ tests/groups.js | 2 ++ tests/messaging.js | 4 ++++ tests/mocks/databasemock.js | 4 ++++ tests/topics.js | 20 ++++++++++++++++++++ tests/user.js | 7 +++++++ 64 files changed, 359 insertions(+), 23 deletions(-) diff --git a/app.js b/app.js index 6fd215ad61..2158d61282 100644 --- a/app.js +++ b/app.js @@ -285,6 +285,11 @@ function upgrade() { function activate() { require('./src/database').init(function(err) { + if (err) { + winston.error(err.stack); + process.exit(1); + } + var plugin = nconf.get('_')[1] ? nconf.get('_')[1] : nconf.get('activate'), db = require('./src/database'); @@ -296,9 +301,19 @@ function activate() { function listPlugins() { require('./src/database').init(function(err) { + if (err) { + winston.error(err.stack); + process.exit(1); + } + var db = require('./src/database'); db.getSortedSetRange('plugins:active', 0, -1, function(err, plugins) { + if (err) { + winston.error(err.stack); + process.exit(1); + } + winston.info('Active plugins: \n\t - ' + plugins.join('\n\t - ')); process.exit(); }); diff --git a/install/web.js b/install/web.js index 0f4e645e8a..b60614de07 100644 --- a/install/web.js +++ b/install/web.js @@ -130,6 +130,10 @@ function compileLess(callback) { } fs.readFile(path.join(__dirname, '../public/less/install.less'), function(err, style) { + if (err) { + return winston.error('Unable to read LESS install file: ', err); + } + less.render(style.toString(), function(err, css) { if(err) { return winston.error('Unable to compile LESS: ', err); diff --git a/public/src/admin/admin.js b/public/src/admin/admin.js index a90967c2e0..add13c30cc 100644 --- a/public/src/admin/admin.js +++ b/public/src/admin/admin.js @@ -82,7 +82,7 @@ socket.emit('admin.restart'); }); - mousetrap.bind('/', function(e) { + mousetrap.bind('/', function(event) { $('#acp-search input').focus(); return false; diff --git a/public/src/admin/advanced/errors.js b/public/src/admin/advanced/errors.js index 52d6427240..3977778b5a 100644 --- a/public/src/admin/advanced/errors.js +++ b/public/src/admin/advanced/errors.js @@ -14,6 +14,10 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { bootbox.confirm('Are you sure you wish to clear the 404 error logs?', function(ok) { if (ok) { socket.emit('admin.errors.clear', {}, function(err) { + if (err) { + return app.alertError(err.message); + } + ajaxify.refresh(); app.alertSuccess('"404 Not Found" errors cleared'); }); diff --git a/public/src/admin/advanced/logs.js b/public/src/admin/advanced/logs.js index ea0503d8a6..8411effabc 100644 --- a/public/src/admin/advanced/logs.js +++ b/public/src/admin/advanced/logs.js @@ -10,7 +10,7 @@ define('admin/advanced/logs', function() { // Affix menu $('.affix').affix(); - $('.logs').find('button[data-action]').on('click', function(e) { + $('.logs').find('button[data-action]').on('click', function(event) { var btnEl = $(this), action = btnEl.attr('data-action'); diff --git a/public/src/admin/appearance/customise.js b/public/src/admin/appearance/customise.js index a85fd663ad..e76bb9d3e4 100644 --- a/public/src/admin/appearance/customise.js +++ b/public/src/admin/appearance/customise.js @@ -15,7 +15,7 @@ define('admin/appearance/customise', ['admin/settings'], function(Settings) { customCSS.setTheme("ace/theme/twilight"); customCSS.getSession().setMode("ace/mode/css"); - customCSS.on('change', function(e) { + customCSS.on('change', function(event) { app.flags = app.flags || {}; app.flags._unsaved = true; $('#customCSS-holder').val(customCSS.getValue()); @@ -24,7 +24,7 @@ define('admin/appearance/customise', ['admin/settings'], function(Settings) { customHTML.setTheme("ace/theme/twilight"); customHTML.getSession().setMode("ace/mode/html"); - customHTML.on('change', function(e) { + customHTML.on('change', function(event) { app.flags = app.flags || {}; app.flags._unsaved = true; $('#customHTML-holder').val(customHTML.getValue()); diff --git a/public/src/admin/extend/plugins.js b/public/src/admin/extend/plugins.js index b4e8767184..eccb94f527 100644 --- a/public/src/admin/extend/plugins.js +++ b/public/src/admin/extend/plugins.js @@ -20,6 +20,9 @@ define('admin/extend/plugins', function() { pluginID = pluginEl.attr('data-plugin-id'); var btn = $('#' + pluginID + ' [data-action="toggleActive"]'); socket.emit('admin.plugins.toggleActive', pluginID, function(err, status) { + if (err) { + return app.alertError(err); + } btn.html(' ' + (status.active ? 'Deactivate' : 'Activate')); btn.toggleClass('btn-warning', status.active).toggleClass('btn-success', !status.active); diff --git a/public/src/admin/general/dashboard.js b/public/src/admin/general/dashboard.js index 1224d2ace2..f32cb2d839 100644 --- a/public/src/admin/general/dashboard.js +++ b/public/src/admin/general/dashboard.js @@ -306,6 +306,9 @@ define('admin/general/dashboard', ['semver', 'Chart'], function(semver, Chart) { units: units || 'hours', until: until }, function (err, data) { + if (err) { + return app.alertError(err.message); + } if (JSON.stringify(graphData.traffic) === JSON.stringify(data)) { return; } diff --git a/public/src/admin/manage/groups.js b/public/src/admin/manage/groups.js index 8c68837403..3eee1ca08c 100644 --- a/public/src/admin/manage/groups.js +++ b/public/src/admin/manage/groups.js @@ -95,6 +95,10 @@ define('admin/manage/groups', [ sort: 'date' } }, function(err, groups) { + if (err) { + return app.alertError(err.message); + } + templates.parse('admin/manage/groups', 'groups', { groups: groups }, function(html) { diff --git a/public/src/admin/manage/ip-blacklist.js b/public/src/admin/manage/ip-blacklist.js index 9769b3e3bb..949d8ac8fd 100644 --- a/public/src/admin/manage/ip-blacklist.js +++ b/public/src/admin/manage/ip-blacklist.js @@ -29,6 +29,10 @@ define('admin/manage/ip-blacklist', [], function() { socket.emit('blacklist.validate', { rules: blacklist.val() }, function(err, data) { + if (err) { + return app.alertError(err.message); + } + templates.parse('admin/partials/blacklist-validate', data, function(html) { bootbox.alert(html); }); diff --git a/public/src/admin/settings/email.js b/public/src/admin/settings/email.js index a63546f0ba..e6015b3b32 100644 --- a/public/src/admin/settings/email.js +++ b/public/src/admin/settings/email.js @@ -29,7 +29,7 @@ define('admin/settings/email', ['admin/settings'], function(settings) { emailEditor.setTheme("ace/theme/twilight"); emailEditor.getSession().setMode("ace/mode/html"); - emailEditor.on('change', function(e) { + emailEditor.on('change', function(event) { $('#email-editor-holder').val(emailEditor.getValue()); }); @@ -58,4 +58,4 @@ define('admin/settings/email', ['admin/settings'], function(settings) { } return module; -}); \ No newline at end of file +}); diff --git a/public/src/app.js b/public/src/app.js index 7a3a13d080..a23125d5c4 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -40,7 +40,7 @@ app.cacheBuster = null; components.get('user/logout').on('click', app.logout); }); - Visibility.change(function(e, state){ + Visibility.change(function(event, state){ if (state === 'visible') { app.isFocused = true; app.alternatingTitle(''); diff --git a/public/src/client/category.js b/public/src/client/category.js index 98d0063b4b..af0d26b980 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -91,6 +91,10 @@ define('forum/category', [ Category.toBottom = function() { socket.emit('categories.getTopicCount', ajaxify.data.cid, function(err, count) { + if (err) { + return app.alertError(err.message); + } + navigator.scrollBottom(count - 1); }); }; diff --git a/public/src/client/categoryTools.js b/public/src/client/categoryTools.js index 348ff684f8..970ab29d4a 100644 --- a/public/src/client/categoryTools.js +++ b/public/src/client/categoryTools.js @@ -87,6 +87,10 @@ define('forum/categoryTools', ['forum/topic/move', 'topicSelect', 'components', components.get('topic/move-all').on('click', function() { move.init(null, cid, function(err) { + if (err) { + return app.alertError(err.message); + } + ajaxify.refresh(); }); }); diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js index c95120ef77..f71b37886e 100644 --- a/public/src/client/groups/details.js +++ b/public/src/client/groups/details.js @@ -230,7 +230,7 @@ define('forum/groups/details', [ if (ajaxify.data.group.isOwner) { var searchInput = $('[component="groups/members/invite"]'); require(['autocomplete'], function(autocomplete) { - autocomplete.user(searchInput, function(e, selected) { + autocomplete.user(searchInput, function(event, selected) { socket.emit('groups.issueInvite', { toUid: selected.item.user.uid, groupName: ajaxify.data.group.name @@ -259,4 +259,4 @@ define('forum/groups/details', [ } return Details; -}); \ No newline at end of file +}); diff --git a/public/src/client/topic.js b/public/src/client/topic.js index 5f58f38e0b..dcff9d3fe1 100644 --- a/public/src/client/topic.js +++ b/public/src/client/topic.js @@ -127,6 +127,9 @@ define('forum/topic', [ Topic.toBottom = function() { socket.emit('topics.postcount', ajaxify.data.tid, function(err, postCount) { + if (err) { + return app.alertError(err.message); + } if (config.topicPostSort !== 'oldest_to_newest') { postCount = 2; } diff --git a/public/src/client/users.js b/public/src/client/users.js index fe083a13e2..40f221e33f 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -47,6 +47,10 @@ define('forum/users', ['translator'], function(translator) { set: set, after: after }, function(err, data) { + if (err) { + return app.alertError(err.message); + } + if (data && data.users.length) { onUsersLoaded(data); $('#load-more-users-btn').removeClass('disabled'); diff --git a/public/src/modules/notifications.js b/public/src/modules/notifications.js index 533199c31c..dcabe7d0a1 100644 --- a/public/src/modules/notifications.js +++ b/public/src/modules/notifications.js @@ -103,6 +103,10 @@ define('notifications', ['sounds', 'translator', 'components'], function(sound, } socket.emit('notifications.getCount', function(err, count) { + if (err) { + return app.alertError(err.message); + } + Notifications.updateNotifCount(count); }); diff --git a/public/src/modules/search.js b/public/src/modules/search.js index e376c30639..be6ac6a711 100644 --- a/public/src/modules/search.js +++ b/public/src/modules/search.js @@ -142,6 +142,10 @@ define('search', ['navigator', 'translator'], function(nav, translator) { topicPostSort: config.topicPostSort }; socket.emit('posts.getPidIndex', data, function(err, postIndex) { + if (err) { + return app.alertError(err.message); + } + nav.scrollToPost(postIndex, true); }); } else { diff --git a/public/src/modules/settings.js b/public/src/modules/settings.js index 79c150854d..692e0ec7b4 100644 --- a/public/src/modules/settings.js +++ b/public/src/modules/settings.js @@ -508,13 +508,21 @@ define('settings', function () { app.flags._unsaved = false; if (typeof callback === 'function') { - callback(); + callback(err); } else { - app.alert({ - title: 'Settings Saved', - type: 'success', - timeout: 2500 - }); + if (err) { + app.alert({ + title: 'Error while saving settings', + type: 'error', + timeout: 2500 + }); + } else { + app.alert({ + title: 'Settings Saved', + type: 'success', + timeout: 2500 + }); + } } }); } diff --git a/public/src/utils.js b/public/src/utils.js index a1ce6959a4..5d44bcd4fa 100644 --- a/public/src/utils.js +++ b/public/src/utils.js @@ -45,8 +45,16 @@ list.forEach(function(file) { file = dir + '/' + file; fs.stat(file, function(err, stat) { + if (err) { + return done(err); + } + if (stat && stat.isDirectory()) { utils.walk(file, function(err, res) { + if (err) { + return done(err); + } + results = results.concat(res); if (!--pending) { done(null, results); diff --git a/src/controllers/admin/categories.js b/src/controllers/admin/categories.js index 04001e0f65..c33dde5c7c 100644 --- a/src/controllers/admin/categories.js +++ b/src/controllers/admin/categories.js @@ -48,6 +48,10 @@ categoriesController.getAnalytics = function(req, res, next) { name: async.apply(categories.getCategoryField, req.params.category_id, 'name'), analytics: async.apply(analytics.getCategoryAnalytics, req.params.category_id) }, function(err, data) { + if (err) { + return next(err); + } + res.render('admin/manage/category-analytics', data); }); }; diff --git a/src/controllers/admin/errors.js b/src/controllers/admin/errors.js index 4b59932965..d2e29d5eb1 100644 --- a/src/controllers/admin/errors.js +++ b/src/controllers/admin/errors.js @@ -8,20 +8,28 @@ var meta = require('../../meta'), var errorsController = {}; -errorsController.get = function(req, res) { +errorsController.get = function(req, res, next) { async.parallel({ 'not-found': async.apply(meta.errors.get, true), analytics: async.apply(analytics.getErrorAnalytics) }, function(err, data) { + if (err) { + return next(err); + } + res.render('admin/advanced/errors', data); }); }; -errorsController.export = function(req, res) { +errorsController.export = function(req, res, next) { async.waterfall([ async.apply(meta.errors.get, false), async.apply(json2csv) ], function(err, csv) { + if (err) { + return next(err); + } + res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="404.csv"').send(csv); }); }; diff --git a/src/controllers/admin/homepage.js b/src/controllers/admin/homepage.js index f503dd8865..89ef0db928 100644 --- a/src/controllers/admin/homepage.js +++ b/src/controllers/admin/homepage.js @@ -49,6 +49,10 @@ homePageController.get = function(req, res, next) { name: 'Popular' } ].concat(categoryData)}, function(err, data) { + if (err) { + return next(err); + } + data.routes.push({ route: '', name: 'Custom' diff --git a/src/controllers/admin/settings.js b/src/controllers/admin/settings.js index bf0975058a..50c44ef1b7 100644 --- a/src/controllers/admin/settings.js +++ b/src/controllers/admin/settings.js @@ -25,13 +25,21 @@ function renderEmail(req, res, next) { var emailsPath = path.join(__dirname, '../../../public/templates/emails'); utils.walk(emailsPath, function(err, emails) { + if (err) { + return next(err); + } + async.map(emails, function(email, next) { var path = email.replace(emailsPath, '').substr(1).replace('.tpl', ''); fs.readFile(email, function(err, original) { + if (err) { + return next(err); + } + var text = meta.config['email:custom:' + path] ? meta.config['email:custom:' + path] : original.toString(); - next(err, { + next(null, { path: path, fullpath: email, text: text, @@ -39,6 +47,10 @@ function renderEmail(req, res, next) { }); }); }, function(err, emails) { + if (err) { + return next(err); + } + res.render('admin/settings/email', { emails: emails, sendable: emails.filter(function(email) { diff --git a/src/controllers/admin/sounds.js b/src/controllers/admin/sounds.js index 6e7ebf3f19..b583125c5a 100644 --- a/src/controllers/admin/sounds.js +++ b/src/controllers/admin/sounds.js @@ -6,6 +6,10 @@ var soundsController = {}; soundsController.get = function(req, res, next) { meta.sounds.getFiles(function(err, sounds) { + if (err) { + return next(err); + } + sounds = Object.keys(sounds).map(function(name) { return { name: name diff --git a/src/controllers/admin/uploads.js b/src/controllers/admin/uploads.js index 90dae8a243..b507e092cf 100644 --- a/src/controllers/admin/uploads.js +++ b/src/controllers/admin/uploads.js @@ -61,6 +61,10 @@ uploadsController.uploadTouchIcon = function(req, res, next) { if (validateUpload(req, res, next, uploadedFile, allowedTypes)) { file.saveFileToLocal('touchicon-orig.png', 'system', uploadedFile.path, function(err, imageObj) { + if (err) { + return next(err); + } + // Resize the image into squares for use as touch icons at various DPIs async.each(sizes, function(size, next) { async.series([ diff --git a/src/controllers/authentication.js b/src/controllers/authentication.js index bc301b1873..98dc6c1fe4 100644 --- a/src/controllers/authentication.js +++ b/src/controllers/authentication.js @@ -96,6 +96,10 @@ function registerAndLoginUser(req, res, userData, callback) { userData: userData, interstitials: [] }, function(err, data) { + if (err) { + return next(err); + } + // If interstitials are found, save registration attempt into session and abort var deferRegistration = data.interstitials.length; @@ -144,6 +148,10 @@ authenticationController.registerComplete = function(req, res, next) { userData: req.session.registration, interstitials: [] }, function(err, data) { + if (err) { + return next(err); + } + var callbacks = data.interstitials.reduce(function(memo, cur) { if (cur.hasOwnProperty('callback') && typeof cur.callback === 'function') { memo.push(async.apply(cur.callback, req.session.registration, req.body)); @@ -243,6 +251,10 @@ function continueLogin(req, res, next) { winston.verbose('[auth] Triggering password reset for uid ' + userData.uid + ' due to password policy'); req.session.passwordExpired = true; user.reset.generate(userData.uid, function(err, code) { + if (err) { + return res.status(403).send(err.message); + } + res.status(200).send(nconf.get('relative_path') + '/reset/' + code); }); } else { diff --git a/src/controllers/index.js b/src/controllers/index.js index 4ad3d5ab0a..10076846df 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -202,6 +202,10 @@ Controllers.registerInterstitial = function(req, res, next) { userData: req.session.registration, interstitials: [] }, function(err, data) { + if (err) { + return next(err); + } + if (!data.interstitials.length) { return next(); } @@ -212,6 +216,10 @@ Controllers.registerInterstitial = function(req, res, next) { var errors = req.flash('error'); async.parallel(renders, function(err, sections) { + if (err) { + return next(err); + } + res.render('registerComplete', { errors: errors, sections: sections diff --git a/src/groups/cover.js b/src/groups/cover.js index 99f2791a2e..4dae0c2ba4 100644 --- a/src/groups/cover.js +++ b/src/groups/cover.js @@ -7,6 +7,7 @@ var fs = require('fs'); var crypto = require('crypto'); var Jimp = require('jimp'); var mime = require('mime'); +var winston = require('winston'); var db = require('../database'); var file = require('../file'); @@ -70,6 +71,10 @@ module.exports = function(Groups) { ], function (err) { if (err) { return fs.unlink(tempPath, function(unlinkErr) { + if (unlinkErr) { + winston.error(unlinkErr); + } + callback(err); // send back original error }); } diff --git a/src/install.js b/src/install.js index f9fae4ffdf..296e30fdc4 100644 --- a/src/install.js +++ b/src/install.js @@ -257,6 +257,9 @@ function createAdmin(callback) { type: 'string' }], success = function(err, results) { + if (err) { + return callback(err); + } if (!results) { return callback(new Error('aborted')); } diff --git a/src/languages.js b/src/languages.js index 2ad64fd588..70dbf4f4ae 100644 --- a/src/languages.js +++ b/src/languages.js @@ -30,6 +30,10 @@ Languages.get = function(code, key, callback) { var languageData; fs.readFile(path.join(__dirname, '../public/language/', code, key), { encoding: 'utf-8' }, function(err, data) { + if (err && err.code !== 'ENOENT') { + return callback(err); + } + // If language file in core cannot be read, then no language file present try { languageData = JSON.parse(data) || {}; diff --git a/src/meta/css.js b/src/meta/css.js index 478acab284..4834cedc95 100644 --- a/src/meta/css.js +++ b/src/meta/css.js @@ -170,6 +170,10 @@ module.exports = function(Meta) { winston.verbose('[meta/css] Reading stylesheet ' + filePath.split('/').pop() + ' from file'); fs.readFile(filePath, function(err, file) { + if (err) { + return callback(err); + } + Meta.css[filename] = file; callback(); }); diff --git a/src/meta/errors.js b/src/meta/errors.js index 4449a55f57..9c8d1ff772 100644 --- a/src/meta/errors.js +++ b/src/meta/errors.js @@ -20,6 +20,10 @@ module.exports = function(Meta) { Meta.errors.get = function(escape, callback) { db.getSortedSetRevRangeByScoreWithScores('errors:404', 0, -1, '+inf', '-inf', function(err, data) { + if (err) { + return callback(err); + } + data = data.map(function(nfObject) { nfObject.value = escape ? validator.escape(nfObject.value) : nfObject.value; return nfObject; diff --git a/src/meta/js.js b/src/meta/js.js index e25ac45ba0..b781a3b06f 100644 --- a/src/meta/js.js +++ b/src/meta/js.js @@ -267,6 +267,10 @@ module.exports = function(Meta) { } async.map(paths, fs.readFile, function(err, files) { + if (err) { + return callback(err); + } + Meta.js.target[target] = { cache: files[0], map: files[1] || '' diff --git a/src/meta/tags.js b/src/meta/tags.js index 50afe9a1db..4eaba839e6 100644 --- a/src/meta/tags.js +++ b/src/meta/tags.js @@ -89,6 +89,10 @@ module.exports = function(Meta) { plugins.fireHook('filter:meta.getLinkTags', defaultLinks, next); } }, function(err, results) { + if (err) { + return callback(err); + } + meta = results.tags.concat(meta || []).map(function(tag) { if (!tag || typeof tag.content !== 'string') { winston.warn('Invalid meta tag. ', tag); diff --git a/src/meta/themes.js b/src/meta/themes.js index ed6b061db9..dd93a206c2 100644 --- a/src/meta/themes.js +++ b/src/meta/themes.js @@ -56,6 +56,10 @@ module.exports = function(Meta) { }); }, function (err, themes) { + if (err) { + return callback(err); + } + themes = themes.filter(function (theme) { return (theme !== undefined); }); diff --git a/src/middleware/middleware.js b/src/middleware/middleware.js index 62dcc97d4c..e5caf9ba00 100644 --- a/src/middleware/middleware.js +++ b/src/middleware/middleware.js @@ -326,6 +326,10 @@ middleware.processLanguages = function(req, res, next) { if (code && key) { languages.get(code, key[0], function(err, language) { + if (err) { + return next(err); + } + res.status(200).json(language); }); } else { diff --git a/src/plugins.js b/src/plugins.js index 6eba5de2ce..c531dfa27d 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -94,6 +94,10 @@ var middleware; function(next) { // Build language code list fs.readdir(path.join(__dirname, '../public/language'), function(err, directories) { + if (err) { + return next(err); + } + Plugins.languageCodes = directories.filter(function(code) { return code !== 'TODO'; }); @@ -206,7 +210,11 @@ var middleware; } }); } else { - winston.warn('[plugins/' + plugin.id + '] A templates directory was defined for this plugin, but was not found.'); + if (err) { + winston.error(err); + } else { + winston.warn('[plugins/' + plugin.id + '] A templates directory was defined for this plugin, but was not found.'); + } } next(false); @@ -392,7 +400,7 @@ var middleware; next(); }); }, function(err) { - next(null, plugins); + next(err, plugins); }); } ], callback); diff --git a/src/plugins/install.js b/src/plugins/install.js index 1ea826784c..3e3ee42ff3 100644 --- a/src/plugins/install.js +++ b/src/plugins/install.js @@ -96,6 +96,10 @@ module.exports = function(Plugins) { } Plugins.get(id, function(err, pluginData) { + if (err) { + return callback(err); + } + Plugins.fireHook('action:plugin.' + type, id); callback(null, pluginData); }); diff --git a/src/plugins/load.js b/src/plugins/load.js index 70aea70ccd..99019e371f 100644 --- a/src/plugins/load.js +++ b/src/plugins/load.js @@ -221,6 +221,10 @@ module.exports = function(Plugins) { fallbackMap = {}; utils.walk(pathToFolder, function(err, languages) { + if (err) { + return callback(err); + } + async.each(languages, function(pathToLang, next) { fs.readFile(pathToLang, function(err, file) { if (err) { diff --git a/src/posts/flags.js b/src/posts/flags.js index 9eae966cda..dcc2f32f1d 100644 --- a/src/posts/flags.js +++ b/src/posts/flags.js @@ -106,6 +106,10 @@ module.exports = function(Posts) { async.series([ function(next) { db.getSortedSetRange('pid:' + pid + ':flag:uids', 0, -1, function(err, uids) { + if (err) { + return next(err); + } + async.each(uids, function(uid, next) { var nid = 'post_flag:' + pid + ':uid:' + uid; async.parallel([ diff --git a/src/posts/summary.js b/src/posts/summary.js index 885a0e444d..e3e948c292 100644 --- a/src/posts/summary.js +++ b/src/posts/summary.js @@ -101,6 +101,10 @@ module.exports = function(Posts) { next(null, post); }); }, function(err, posts) { + if (err) { + return callback(err); + } + plugins.fireHook('filter:post.getPostSummaryByPids', {posts: posts, uid: uid}, function(err, postData) { callback(err, postData.posts); }); diff --git a/src/reset.js b/src/reset.js index f1e27738e8..56669b6e2d 100644 --- a/src/reset.js +++ b/src/reset.js @@ -82,7 +82,12 @@ function resetTheme(themeId) { type: 'local', id: themeId }, function(err) { - winston.info('[reset] Theme reset to ' + themeId); + if (err) { + winston.warn('[reset] Failed to reset theme to ' + themeId); + } else { + winston.info('[reset] Theme reset to ' + themeId); + } + process.exit(); }); } diff --git a/src/rewards/admin.js b/src/rewards/admin.js index e6c32bc34b..0bde13ac00 100644 --- a/src/rewards/admin.js +++ b/src/rewards/admin.js @@ -46,6 +46,10 @@ rewards.save = function(data, callback) { } async.each(data, save, function(err) { + if (err) { + return callback(err); + } + saveConditions(data, callback); }); }; @@ -125,6 +129,10 @@ function getActiveRewards(callback) { } db.getSetMembers('rewards:list', function(err, rewards) { + if (err) { + return callback(err); + } + async.eachSeries(rewards, load, function(err) { callback(err, activeRewards); }); diff --git a/src/rewards/index.js b/src/rewards/index.js index c811ce933c..bbccab69f3 100644 --- a/src/rewards/index.js +++ b/src/rewards/index.js @@ -111,14 +111,22 @@ function getRewardsByRewardData(rewards, callback) { function checkCondition(reward, method, callback) { method(function(err, value) { + if (err) { + return callback(err); + } + plugins.fireHook('filter:rewards.checkConditional:' + reward.conditional, {left: value, right: reward.value}, function(err, bool) { - callback(bool); + callback(err || bool); }); }); } function giveRewards(uid, rewards, callback) { getRewardsByRewardData(rewards, function(err, rewardData) { + if (err) { + return callback(err); + } + async.each(rewards, function(reward, next) { plugins.fireHook('action:rewards.award:' + reward.rid, {uid: uid, reward: rewardData[rewards.indexOf(reward)]}); db.sortedSetIncrBy('uid:' + uid + ':rewards', 1, reward.id, next); diff --git a/src/routes/debug.js b/src/routes/debug.js index b81938ccc9..a24a159e18 100644 --- a/src/routes/debug.js +++ b/src/routes/debug.js @@ -2,6 +2,7 @@ var express = require('express'), nconf = require('nconf'), + winston = require('winston'), user = require('./../user'), categories = require('./../categories'), topics = require('./../topics'), @@ -16,6 +17,10 @@ module.exports = function(app, middleware, controllers) { } user.getUserData(req.params.uid, function (err, data) { + if (err) { + winston.error(err); + } + if (data) { res.send(data); } else { @@ -28,6 +33,10 @@ module.exports = function(app, middleware, controllers) { router.get('/cid/:cid', function (req, res) { categories.getCategoryData(req.params.cid, function (err, data) { + if (err) { + winston.error(err); + } + if (data) { res.send(data); } else { @@ -38,6 +47,10 @@ module.exports = function(app, middleware, controllers) { router.get('/tid/:tid', function (req, res) { topics.getTopicData(req.params.tid, function (err, data) { + if (err) { + winston.error(err); + } + if (data) { res.send(data); } else { @@ -48,6 +61,10 @@ module.exports = function(app, middleware, controllers) { router.get('/pid/:pid', function (req, res) { posts.getPostData(req.params.pid, function (err, data) { + if (err) { + winston.error(err); + } + if (data) { res.send(data); } else { diff --git a/src/socket.io/helpers.js b/src/socket.io/helpers.js index 706604ec6e..46617c2889 100644 --- a/src/socket.io/helpers.js +++ b/src/socket.io/helpers.js @@ -172,7 +172,15 @@ SocketHelpers.rescindUpvoteNotification = function(pid, fromuid) { notifications.rescind(nid); posts.getPostField(pid, 'uid', function(err, uid) { + if (err) { + return winston.error(err); + } + user.notifications.getUnreadCount(uid, function(err, count) { + if (err) { + return winston.error(err); + } + websockets.in('uid_' + uid).emit('event:notifications.updateCount', count); }); }); diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 44c17ea476..6bb23a0698 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -122,6 +122,10 @@ SocketUser.reset.commit = function(socket, data, callback) { var parsedDate = now.getFullYear() + '/' + (now.getMonth()+1) + '/' + now.getDate(); user.getUserField(uid, 'username', function(err, username) { + if (err) { + return callback(err); + } + emailer.send('reset_notify', uid, { username: username, date: parsedDate, diff --git a/src/socket.io/user/picture.js b/src/socket.io/user/picture.js index cf886b1d48..e71de5f18c 100644 --- a/src/socket.io/user/picture.js +++ b/src/socket.io/user/picture.js @@ -38,6 +38,10 @@ module.exports = function(SocketUser) { type: type, picture: undefined }, function(err, returnData) { + if (err) { + return next(err); + } + next(null, returnData.picture || ''); }); break; diff --git a/src/socket.io/user/profile.js b/src/socket.io/user/profile.js index 52c9fcd801..48c0f0fa49 100644 --- a/src/socket.io/user/profile.js +++ b/src/socket.io/user/profile.js @@ -29,6 +29,10 @@ module.exports = function(SocketUser) { } user.isAdministrator(socket.uid, function(err, isAdmin) { + if (err) { + return callback(err); + } + if (!isAdmin && data.uid !== socket.uid) { return callback(new Error('[[error:no-privileges]]')); } diff --git a/src/upgrade.js b/src/upgrade.js index ae3877458d..317f1837da 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -46,6 +46,10 @@ Upgrade.upgrade = function(callback) { function(next) { // Prepare for upgrade & check to make sure the upgrade is possible db.get('schemaDate', function(err, value) { + if (err) { + return next(err); + } + if(!value) { db.set('schemaDate', latestSchema, function() { next(); @@ -506,8 +510,16 @@ Upgrade.upgrade = function(callback) { var privilegesAPI = require('./privileges'); db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { + if (err) { + return next(err); + } + async.eachSeries(cids, function(cid, next) { privilegesAPI.categories.list(cid, function(err, data) { + if (err) { + return next(err); + } + var groups = data.groups; var users = data.users; @@ -628,6 +640,10 @@ Upgrade.upgrade = function(callback) { var meta = require('./meta'); db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { + if (err) { + return next(err); + } + async.eachSeries(cids, function(cid, next) { privilegesAPI.categories.list(cid, function(err, data) { if (err) { @@ -694,8 +710,16 @@ Upgrade.upgrade = function(callback) { var privilegesAPI = require('./privileges'); db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { + if (err) { + return next(err); + } + async.eachSeries(cids, function(cid, next) { privilegesAPI.categories.list(cid, function(err, data) { + if (err) { + return next(err); + } + var groups = data.groups; var users = data.users; diff --git a/src/user/auth.js b/src/user/auth.js index f2fa917962..b8ff96053b 100644 --- a/src/user/auth.js +++ b/src/user/auth.js @@ -101,7 +101,7 @@ module.exports = function(User) { async.each(expiredSids, function(sid, next) { User.auth.revokeSession(sid, uid, next); }, function(err) { - next(null, sessions); + next(err, sessions); }); } ], function (err, sessions) { diff --git a/src/user/digest.js b/src/user/digest.js index 81b6ea0220..f3978bd8e5 100644 --- a/src/user/digest.js +++ b/src/user/digest.js @@ -60,6 +60,10 @@ var utils = require('../../public/src/utils'); Digest.getSubscribers = function(interval, callback) { db.getSortedSetRange('digest:' + interval + ':uids', 0, -1, function(err, subscribers) { + if (err) { + return callback(err); + } + plugins.fireHook('filter:digest.subscribers', { interval: interval, subscribers: subscribers diff --git a/src/user/follow.js b/src/user/follow.js index 094d33c460..7295f01519 100644 --- a/src/user/follow.js +++ b/src/user/follow.js @@ -85,6 +85,10 @@ module.exports = function(User) { start: start, stop: stop }, function(err, data) { + if (err) { + return callback(err); + } + User.getUsers(data.uids, uid, callback); }); }); diff --git a/src/user/picture.js b/src/user/picture.js index 38d013cab0..78ad131ab4 100644 --- a/src/user/picture.js +++ b/src/user/picture.js @@ -200,6 +200,10 @@ module.exports = function(User) { ], function(err) { if (err) { return fs.unlink(data.file.path, function(unlinkErr) { + if (unlinkErr) { + winston.error(unlinkErr); + } + callback(err); // send back the original error }); } diff --git a/src/user/profile.js b/src/user/profile.js index 8b2a83f152..34fb24467c 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -49,6 +49,10 @@ module.exports = function(User) { } User.getUserField(uid, 'email', function(err, email) { + if (err) { + return next(err); + } + if(email === data.email) { return next(); } diff --git a/tests/categories.js b/tests/categories.js index c5bbee22cc..b607e6fc0a 100644 --- a/tests/categories.js +++ b/tests/categories.js @@ -25,6 +25,8 @@ describe('Categories', function() { blockclass: 'category-blue', order: '5' }, function(err, category) { + assert.equal(err, null); + categoryObj = category; done.apply(this, arguments); }); @@ -41,6 +43,8 @@ describe('Categories', function() { stop: -1, uid: 0 }, function(err, categoryData) { + assert.equal(err, null); + assert(categoryData); assert.equal(categoryObj.name, categoryData.name); assert.equal(categoryObj.description, categoryData.description); @@ -60,6 +64,8 @@ describe('Categories', function() { stop: 10, uid: 0 }, function(err, result) { + assert.equal(err, null); + assert(Array.isArray(result.topics)); assert(result.topics.every(function(topic) { return topic instanceof Object; @@ -79,6 +85,7 @@ describe('Categories', function() { uid: 0, targetUid: 1 }, function(err, result) { + assert.equal(err, null); assert(Array.isArray(result.topics)); assert(result.topics.every(function(topic) { return topic instanceof Object && topic.uid === '1'; diff --git a/tests/database/list.js b/tests/database/list.js index 137c465c2e..c008a0f784 100644 --- a/tests/database/list.js +++ b/tests/database/list.js @@ -125,6 +125,7 @@ describe('List methods', function() { assert.equal(arguments.length, 1); db.getListRange('testList5', 0, -1, function(err, list) { + assert.equal(err, null); assert.equal(Array.isArray(list), true); assert.equal(list.length, 2); assert.equal(list.indexOf('1'), -1); @@ -148,6 +149,7 @@ describe('List methods', function() { assert.equal(err, null); assert.equal(arguments.length, 1); db.getListRange('testList6', 0, -1, function(err, list) { + assert.equal(err, null); assert.equal(list.length, 3); assert.deepEqual(list, ['1', '2', '3']); done(); diff --git a/tests/groups.js b/tests/groups.js index 6c30bddd77..43b1857b99 100644 --- a/tests/groups.js +++ b/tests/groups.js @@ -270,6 +270,7 @@ describe('Groups', function() { if (err) return done(err); Groups.isMember(1, 'Test', function(err, isMember) { + assert.equal(err, null); assert.strictEqual(true, isMember); done(); @@ -284,6 +285,7 @@ describe('Groups', function() { if (err) return done(err); Groups.isMember(1, 'Test', function(err, isMember) { + assert.equal(err, null); assert.strictEqual(false, isMember); done(); diff --git a/tests/messaging.js b/tests/messaging.js index 3092e42b35..e7a936bae1 100644 --- a/tests/messaging.js +++ b/tests/messaging.js @@ -17,6 +17,10 @@ describe('Messaging Library', function() { async.apply(User.create, { username: 'baz', password: 'quux' }), // restricted user async.apply(User.create, { username: 'herp', password: 'derp' }) // regular user ], function(err, uids) { + if (err) { + return done(err); + } + testUids = uids; async.parallel([ async.apply(Groups.join, 'administrators', uids[0]), diff --git a/tests/mocks/databasemock.js b/tests/mocks/databasemock.js index a895d25c8a..b18d19e338 100644 --- a/tests/mocks/databasemock.js +++ b/tests/mocks/databasemock.js @@ -75,6 +75,10 @@ before(function(done) { db.init(function(err) { + if (err) { + return done(err); + } + //Clean up db.flushdb(function(err) { if(err) { diff --git a/tests/topics.js b/tests/topics.js index bf890f3ebe..575ce6a0b1 100644 --- a/tests/topics.js +++ b/tests/topics.js @@ -23,6 +23,10 @@ describe('Topic\'s', function() { }; User.create({username: userData.username, password: userData.password, email: userData.email}, function(err, uid) { + if (err) { + return done(err); + } + categories.create({ name: 'Test Category', description: 'Test category created by testing script', @@ -30,6 +34,10 @@ describe('Topic\'s', function() { blockclass: 'category-blue', order: '5' }, function(err, category) { + if (err) { + return done(err); + } + categoryObj = category; topic = { @@ -91,6 +99,10 @@ describe('Topic\'s', function() { before(function(done) { topics.post({uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) { + if (err) { + return done(err); + } + newTopic = result.topicData; newPost = result.postData; done(); @@ -134,6 +146,10 @@ describe('Topic\'s', function() { before(function(done) { topics.post({uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) { + if (err) { + return done(err); + } + newTopic = result.topicData; newPost = result.postData; done(); @@ -236,6 +252,10 @@ describe('Topic\'s', function() { async.waterfall([ function(done){ topics.post({uid: topic.userId, title: 'Topic to be ignored', content: 'Just ignore me, please!', cid: topic.categoryId}, function(err, result) { + if (err) { + return done(err); + } + newTopic = result.topicData; newTid = newTopic.tid; done(); diff --git a/tests/user.js b/tests/user.js index 30a835fe83..32f43c7dbf 100644 --- a/tests/user.js +++ b/tests/user.js @@ -28,6 +28,10 @@ describe('User', function() { description: 'A test', order: 1 }, function(err, categoryObj) { + if (err) { + return done(err); + } + testCid = categoryObj.cid; done(); }); @@ -67,6 +71,7 @@ describe('User', function() { describe('.isModerator()', function() { it('should return false', function(done) { User.isModerator(testUid, testCid, function(err, isModerator) { + assert.equal(err, null); assert.equal(isModerator, false); done(); }); @@ -74,6 +79,7 @@ describe('User', function() { it('should return two false results', function(done) { User.isModerator([testUid, testUid], testCid, function(err, isModerator) { + assert.equal(err, null); assert.equal(isModerator[0], false); assert.equal(isModerator[1], false); done(); @@ -82,6 +88,7 @@ describe('User', function() { it('should return two false results', function(done) { User.isModerator(testUid, [testCid, testCid], function(err, isModerator) { + assert.equal(err, null); assert.equal(isModerator[0], false); assert.equal(isModerator[1], false); done();