backend-manager 5.9.26 → 5.9.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -3,6 +3,11 @@ const moment = require('moment');
|
|
|
3
3
|
// Must match the SEND_AT_LIMIT in email.js
|
|
4
4
|
const SEND_AT_LIMIT = 71;
|
|
5
5
|
|
|
6
|
+
// Permanent failures (bad data, deleted user) are removed immediately.
|
|
7
|
+
// Temporary failures (network, SendGrid outage) retry up to MAX_RETRIES
|
|
8
|
+
// before being removed. With the 10-minute cron cycle, 5 retries ≈ 50 minutes.
|
|
9
|
+
const MAX_RETRIES = 5;
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* Email queue processor cron job
|
|
8
13
|
*
|
|
@@ -32,25 +37,35 @@ module.exports = async ({ Manager, assistant, context, libraries }) => {
|
|
|
32
37
|
assistant.log(`Processing ${snapshot.size} queued email(s)...`);
|
|
33
38
|
|
|
34
39
|
const email = Manager.Email(assistant);
|
|
40
|
+
let sent = 0;
|
|
41
|
+
let dropped = 0;
|
|
42
|
+
let retried = 0;
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
const
|
|
44
|
+
await Promise.allSettled(snapshot.docs.map(async (doc) => {
|
|
45
|
+
const data = doc.data();
|
|
46
|
+
const { settings } = data;
|
|
38
47
|
const emailId = doc.id;
|
|
48
|
+
const retries = data.retries || 0;
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const failed = results.filter(r => r.status === 'rejected').length;
|
|
50
|
+
try {
|
|
51
|
+
const result = await email.send(settings);
|
|
52
|
+
assistant.log(`Queued email ${emailId} ${result.status}`);
|
|
53
|
+
await doc.ref.delete();
|
|
54
|
+
sent++;
|
|
55
|
+
} catch (e) {
|
|
56
|
+
const isPermanent = e.code >= 400 && e.code < 500;
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
if (isPermanent || retries >= MAX_RETRIES) {
|
|
59
|
+
assistant.error(`Dropping queued email ${emailId} after ${retries} retries: ${e.message}`);
|
|
60
|
+
await doc.ref.delete();
|
|
61
|
+
dropped++;
|
|
62
|
+
} else {
|
|
63
|
+
assistant.warn(`Queued email ${emailId} failed (retry ${retries + 1}/${MAX_RETRIES}): ${e.message}`);
|
|
64
|
+
await doc.ref.set({ retries: retries + 1, lastError: e.message }, { merge: true });
|
|
65
|
+
retried++;
|
|
66
|
+
}
|
|
52
67
|
}
|
|
53
|
-
}
|
|
68
|
+
}));
|
|
54
69
|
|
|
55
|
-
assistant.log(`Completed! (${sent} sent, ${
|
|
70
|
+
assistant.log(`Completed! (${sent} sent, ${dropped} dropped, ${retried} retried)`);
|
|
56
71
|
};
|