Skip to content

Commit 62c8ec1

Browse files
authored
🐛 fix: implement exponential backoff for ticket creation retries
1 parent b022879 commit 62c8ec1

File tree

2 files changed

+44
-24
lines changed

2 files changed

+44
-24
lines changed

src/events/threadCreate.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,11 @@ module.exports = {
7575

7676
logger.info(`Forum post converted to ticket: #${ticket.friendlyId}`);
7777
} catch (error) {
78-
// Log and handle errors during ticket creation.
79-
logger.error('Error creating ticket from forum post:', error);
78+
if (error.message.includes('timeout')) {
79+
logger.error('Ticket creation is taking longer than expected. Please wait and try again.');
80+
} else {
81+
logger.error('An error occurred while creating the ticket:', error.message);
82+
}
8083
try {
8184
// Notify users in the thread about the error.
8285
const errorEmbed = new EmbedBuilder()

src/services/unthread.js

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -131,33 +131,50 @@ async function createTicket(user, title, issue, email) {
131131
if (!data.friendlyId && data.id) {
132132
logger.debug(`friendlyId not found in initial response. Starting polling for ticket ${data.id}`);
133133

134-
const maxRetries = 50; // Increased to 50 attempts
135-
const retryDelay = 60000; // Set to 60000ms (60 seconds)
134+
// Implementation of exponential backoff for retry logic
135+
const maxRetries = 18; // Increased from 12 to 18 attempts
136+
const baseDelayMs = 1000; // Start with 1 second
137+
const maxDelayMs = 60000; // Increased from 40000 to 60000 ms (60 seconds)
138+
const jitterFactor = 0.1; // Add up to 10% random jitter
136139

137140
for (let attempt = 0; attempt < maxRetries; attempt++) {
138-
logger.debug(`Waiting for friendlyId, attempt ${attempt + 1}/${maxRetries}`);
139-
await new Promise(resolve => setTimeout(resolve, retryDelay));
141+
// Calculate exponential delay with jitter
142+
let delayMs = Math.min(
143+
maxDelayMs,
144+
baseDelayMs * Math.pow(2, attempt)
145+
);
140146

141-
const ticketResponse = await fetch(`https://api.unthread.io/api/conversations/${data.id}`, {
142-
method: 'GET',
143-
headers: {
144-
'Content-Type': 'application/json',
145-
'X-API-KEY': process.env.UNTHREAD_API_KEY,
146-
},
147-
});
147+
// Add random jitter to prevent synchronized retries
148+
delayMs = delayMs * (1 + jitterFactor * Math.random());
148149

149-
if (!ticketResponse.ok) {
150-
logger.error(`Failed to fetch ticket: ${ticketResponse.status}, response: ${await ticketResponse.text()}`);
151-
continue;
152-
}
153-
154-
const updatedData = await ticketResponse.json();
155-
logger.debug(`Polling result (attempt ${attempt + 1}):`, JSON.stringify(updatedData, null, 2));
150+
logger.debug(`Waiting for friendlyId, attempt ${attempt + 1}/${maxRetries} with delay of ${Math.round(delayMs)}ms`);
151+
await new Promise(resolve => setTimeout(resolve, delayMs));
156152

157-
if (updatedData.friendlyId) {
158-
data = updatedData;
159-
logger.info(`Found friendlyId: ${data.friendlyId} after ${attempt + 1} attempts`);
160-
break;
153+
try {
154+
const ticketResponse = await fetch(`https://api.unthread.io/api/conversations/${data.id}`, {
155+
method: 'GET',
156+
headers: {
157+
'Content-Type': 'application/json',
158+
'X-API-KEY': process.env.UNTHREAD_API_KEY,
159+
},
160+
});
161+
162+
if (!ticketResponse.ok) {
163+
logger.error(`Failed to fetch ticket: ${ticketResponse.status}, response: ${await ticketResponse.text()}`);
164+
continue;
165+
}
166+
167+
const updatedData = await ticketResponse.json();
168+
logger.debug(`Polling result (attempt ${attempt + 1}):`, JSON.stringify(updatedData, null, 2));
169+
170+
if (updatedData.friendlyId) {
171+
data = updatedData;
172+
logger.info(`Found friendlyId: ${data.friendlyId} after ${attempt + 1} attempts`);
173+
break;
174+
}
175+
} catch (error) {
176+
logger.error(`Error during polling attempt ${attempt + 1}:`, error);
177+
// Continue the retry loop rather than failing immediately on network errors
161178
}
162179
}
163180
}

0 commit comments

Comments
 (0)