Skip to content

Commit 43f2a74

Browse files
committed
fix: revert jQuery to 3.7.1 and harden export resilience
Revert jQuery 4.0.0 to 3.7.1 for Bootstrap 4.6.2 compatibility. Add unsigned right shift to export test score calculation to match production logic. Wrap Gmail getLabels() in try-catch so label fetch failures degrade gracefully during exports. Reconcile missing Outlook batch responses so silently dropped requests produce explicit errors.
1 parent 839ce55 commit 43f2a74

File tree

5 files changed

+28
-10
lines changed

5 files changed

+28
-10
lines changed

lib/email-client/gmail-client.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,10 +1363,14 @@ class GmailClient extends BaseClient {
13631363
await this.prepare();
13641364

13651365
// Pre-fetch labels to resolve label IDs to names
1366-
const labelsResult = await this.getLabels();
13671366
const labelMap = new Map();
1368-
for (const label of labelsResult || []) {
1369-
labelMap.set(label.id, label.name);
1367+
try {
1368+
const labelsResult = await this.getLabels();
1369+
for (const label of labelsResult || []) {
1370+
labelMap.set(label.id, label.name);
1371+
}
1372+
} catch (err) {
1373+
this.logger.warn({ msg: 'Failed to fetch labels for export, using raw label IDs', account: this.account, err });
13701374
}
13711375

13721376
const results = [];

lib/email-client/outlook-client.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1741,13 +1741,16 @@ class OutlookClient extends BaseClient {
17411741
continue;
17421742
}
17431743

1744-
// Process batch responses - match by request ID
1744+
// Process batch responses - match by request ID and track which were received
1745+
const respondedIds = new Set();
17451746
for (const response of responseData?.responses || []) {
17461747
const emailId = messageMap.get(response.id);
17471748
if (!emailId) {
17481749
continue;
17491750
}
17501751

1752+
respondedIds.add(response.id);
1753+
17511754
if (response.status >= 200 && response.status < 300 && response.body) {
17521755
try {
17531756
const messageData = response.body;
@@ -1820,6 +1823,17 @@ class OutlookClient extends BaseClient {
18201823
});
18211824
}
18221825
}
1826+
1827+
// Reconcile: detect messages that got no response from the batch API
1828+
for (const [reqId, emailId] of messageMap) {
1829+
if (!respondedIds.has(reqId)) {
1830+
results.push({
1831+
messageId: emailId,
1832+
data: null,
1833+
error: { message: 'No response received from batch API', code: 'EMISSING_RESPONSE' }
1834+
});
1835+
}
1836+
}
18231837
}
18241838

18251839
return results;

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
"ioredis": "5.9.2",
8888
"ipaddr.js": "2.3.0",
8989
"joi": "17.13.3",
90-
"jquery": "4.0.0",
90+
"jquery": "3.7.1",
9191
"libbase64": "1.3.0",
9292
"libmime": "5.3.7",
9393
"libqp": "2.1.1",

test/export-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function calculateScore(timestamp, messageId, folder, uid) {
2626
// Generate tiebreaker from SHA-256 hash of composite key (0-999999 range)
2727
const uniqueKey = `${folder || ''}:${messageId || ''}:${uid || ''}`;
2828
const hash = crypto.createHash('sha256').update(uniqueKey).digest();
29-
const tiebreaker = ((hash[0] << 16) | (hash[1] << 8) | hash[2]) % 1000000;
29+
const tiebreaker = (((hash[0] << 16) | (hash[1] << 8) | hash[2]) >>> 0) % 1000000;
3030

3131
return baseSeconds * 1000000 + tiebreaker;
3232
}

0 commit comments

Comments
 (0)