fix: #9339, only log email errors once per digest, notification push

show notice in acp
v1.18.x
Barış Soner Uşaklı 4 years ago
parent 3f42d40c78
commit 3aa26c4df2

@ -30,6 +30,7 @@
"upgrade-available": "<p>A new version (v%1) has been released. Consider <a href=\"https://docs.nodebb.org/configuring/upgrade/\" target=\"_blank\">upgrading your NodeBB</a>.</p>", "upgrade-available": "<p>A new version (v%1) has been released. Consider <a href=\"https://docs.nodebb.org/configuring/upgrade/\" target=\"_blank\">upgrading your NodeBB</a>.</p>",
"prerelease-upgrade-available": "<p>This is an outdated pre-release version of NodeBB. A new version (v%1) has been released. Consider <a href=\"https://docs.nodebb.org/configuring/upgrade/\" target=\"_blank\">upgrading your NodeBB</a>.</p>", "prerelease-upgrade-available": "<p>This is an outdated pre-release version of NodeBB. A new version (v%1) has been released. Consider <a href=\"https://docs.nodebb.org/configuring/upgrade/\" target=\"_blank\">upgrading your NodeBB</a>.</p>",
"prerelease-warning": "<p>This is a <strong>pre-release</strong> version of NodeBB. Unintended bugs may occur. <i class=\"fa fa-exclamation-triangle\"></i></p>", "prerelease-warning": "<p>This is a <strong>pre-release</strong> version of NodeBB. Unintended bugs may occur. <i class=\"fa fa-exclamation-triangle\"></i></p>",
"fallback-emailer-not-found": "Fallback emailer not found!",
"running-in-development": "<span>Forum is running in development mode. The forum may be open to potential vulnerabilities; please contact your system administrator.</span>", "running-in-development": "<span>Forum is running in development mode. The forum may be open to potential vulnerabilities; please contact your system administrator.</span>",
"latest-lookup-failed": "<p>Failed to look up latest available version of NodeBB</p>", "latest-lookup-failed": "<p>Failed to look up latest available version of NodeBB</p>",

@ -13,6 +13,7 @@ const plugins = require('../../plugins');
const user = require('../../user'); const user = require('../../user');
const topics = require('../../topics'); const topics = require('../../topics');
const utils = require('../../utils'); const utils = require('../../utils');
const emailer = require('../../emailer');
const dashboardController = module.exports; const dashboardController = module.exports;
@ -56,6 +57,13 @@ async function getNotices() {
}, },
]; ];
if (emailer.fallbackNotFound) {
notices.push({
done: false,
notDoneText: '[[admin/dashboard:fallback-emailer-not-found]]',
});
}
if (global.env !== 'production') { if (global.env !== 'production') {
notices.push({ notices.push({
done: false, done: false,

@ -25,6 +25,8 @@ const Emailer = module.exports;
let prevConfig; let prevConfig;
let app; let app;
Emailer.fallbackNotFound = false;
Emailer.transports = { Emailer.transports = {
sendmail: nodemailer.createTransport({ sendmail: nodemailer.createTransport({
sendmail: true, sendmail: true,
@ -312,7 +314,8 @@ Emailer.sendToEmail = async (template, email, language, params) => {
headers: params.headers, headers: params.headers,
rtl: params.rtl, rtl: params.rtl,
}); });
const usingFallback = !Plugins.hooks.hasListeners('filter:email.send') &&
!Plugins.hooks.hasListeners('static:email.send');
try { try {
if (Plugins.hooks.hasListeners('filter:email.send')) { if (Plugins.hooks.hasListeners('filter:email.send')) {
// Deprecated, remove in v1.18.0 // Deprecated, remove in v1.18.0
@ -323,7 +326,8 @@ Emailer.sendToEmail = async (template, email, language, params) => {
await Emailer.sendViaFallback(data); await Emailer.sendViaFallback(data);
} }
} catch (err) { } catch (err) {
if (err && err.code === 'ENOENT') { if (err.code === 'ENOENT' && usingFallback) {
Emailer.fallbackNotFound = true;
throw new Error('[[error:sendmail-not-found]]'); throw new Error('[[error:sendmail-not-found]]');
} else { } else {
throw err; throw err;

@ -186,6 +186,7 @@ async function pushToUids(uids, notification) {
} }
body = posts.relativeToAbsolute(body, posts.urlRegex); body = posts.relativeToAbsolute(body, posts.urlRegex);
body = posts.relativeToAbsolute(body, posts.imgRegex); body = posts.relativeToAbsolute(body, posts.imgRegex);
let errorLogged = false;
await async.eachLimit(uids, 3, async (uid) => { await async.eachLimit(uids, 3, async (uid) => {
await emailer.send('notification', uid, { await emailer.send('notification', uid, {
path: notification.path, path: notification.path,
@ -195,7 +196,12 @@ async function pushToUids(uids, notification) {
body: body, body: body,
notification: notification, notification: notification,
showUnsubscribe: true, showUnsubscribe: true,
}).catch(err => winston.error(`[emailer.send] ${err.stack}`)); }).catch((err) => {
if (!errorLogged) {
winston.error(`[emailer.send] ${err.stack}`);
errorLogged = true;
}
});
}); });
} }

@ -86,10 +86,14 @@ User.sendValidationEmail = async function (socket, uids) {
} }
const failed = []; const failed = [];
let errorLogged = false;
await async.eachLimit(uids, 50, async (uid) => { await async.eachLimit(uids, 50, async (uid) => {
await user.email.sendValidationEmail(uid, { force: true }).catch((err) => { await user.email.sendValidationEmail(uid, { force: true }).catch((err) => {
winston.error(`[user.create] Validation email failed to send\n[emailer.send] ${err.stack}`); if (!errorLogged) {
winston.error(`[user.create] Validation email failed to send\n[emailer.send] ${err.stack}`);
errorLogged = true;
}
failed.push(uid); failed.push(uid);
}); });
}); });

@ -100,7 +100,7 @@ Digest.send = async function (data) {
if (!data || !data.subscribers || !data.subscribers.length) { if (!data || !data.subscribers || !data.subscribers.length) {
return emailsSent; return emailsSent;
} }
let errorLogged = false;
await batch.processArray(data.subscribers, async (uids) => { await batch.processArray(data.subscribers, async (uids) => {
let userData = await user.getUsersFields(uids, ['uid', 'email', 'email:confirmed', 'username', 'userslug', 'lastonline']); let userData = await user.getUsersFields(uids, ['uid', 'email', 'email:confirmed', 'username', 'userslug', 'lastonline']);
userData = userData.filter(u => u && u.email && (!meta.config.requireEmailConfirmation || u['email:confirmed'])); userData = userData.filter(u => u && u.email && (!meta.config.requireEmailConfirmation || u['email:confirmed']));
@ -139,7 +139,12 @@ Digest.send = async function (data) {
popularTopics: topics.popular, popularTopics: topics.popular,
interval: data.interval, interval: data.interval,
showUnsubscribe: true, showUnsubscribe: true,
}).catch(err => winston.error(`[user/jobs] Could not send digest email\n[emailer.send] ${err.stack}`)); }).catch((err) => {
if (!errorLogged) {
winston.error(`[user/jobs] Could not send digest email\n[emailer.send] ${err.stack}`);
errorLogged = true;
}
});
})); }));
if (data.interval !== 'alltime') { if (data.interval !== 'alltime') {
const now = Date.now(); const now = Date.now();

Loading…
Cancel
Save