mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-03 07:42:03 +00:00
cancel in-flight decryption requests on timeout
This commit is contained in:
parent
f0f5b54768
commit
1e9e9471b7
@ -29,17 +29,25 @@ export const useDecryptContent = () => {
|
||||
return await inProgressMap.current.get(cacheKey);
|
||||
} catch (error) {
|
||||
// If the existing promise rejects, we'll try again below
|
||||
console.warn('Previous decryption attempt failed, retrying');
|
||||
if (error.name !== 'AbortError') {
|
||||
console.warn('Previous decryption attempt failed, retrying');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create abort controller for this request
|
||||
const abortController = new AbortController();
|
||||
|
||||
// Create a new decryption promise for this content
|
||||
const decryptPromise = (async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
const response = await axios.post('/api/decrypt', { encryptedContent });
|
||||
const response = await axios.post('/api/decrypt',
|
||||
{ encryptedContent },
|
||||
{ signal: abortController.signal }
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`Failed to decrypt: ${response.statusText}`);
|
||||
@ -52,6 +60,11 @@ export const useDecryptContent = () => {
|
||||
|
||||
return decryptedContent;
|
||||
} catch (error) {
|
||||
// Handle abort errors specifically
|
||||
if (axios.isCancel(error)) {
|
||||
throw new DOMException('Decryption aborted', 'AbortError');
|
||||
}
|
||||
|
||||
setError(error.message || 'Decryption failed');
|
||||
// Re-throw to signal failure to awaiter
|
||||
throw error;
|
||||
@ -62,9 +75,19 @@ export const useDecryptContent = () => {
|
||||
}
|
||||
})();
|
||||
|
||||
// Store the promise in our map
|
||||
// Store the promise and abort controller in our map
|
||||
const abortablePromise = {
|
||||
promise: decryptPromise,
|
||||
abort: () => abortController.abort()
|
||||
};
|
||||
|
||||
inProgressMap.current.set(cacheKey, decryptPromise);
|
||||
|
||||
// Function to handle timeouts from parent callers
|
||||
decryptPromise.cancel = () => {
|
||||
abortController.abort();
|
||||
};
|
||||
|
||||
// Return the promise
|
||||
try {
|
||||
return await decryptPromise;
|
||||
|
@ -196,19 +196,32 @@ const useDecryption = (session, paidCourse, course, lessons, setLessons, router)
|
||||
processingRef.current = true;
|
||||
setLoading(true);
|
||||
|
||||
// Start the decryption process
|
||||
const decryptionPromise = decryptContent(currentLesson.content);
|
||||
|
||||
// Add safety timeout to prevent infinite processing
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Decryption timeout')), 10000)
|
||||
);
|
||||
let timeoutId;
|
||||
const timeoutPromise = new Promise((_, reject) => {
|
||||
timeoutId = setTimeout(() => {
|
||||
// Cancel the in-flight request when timeout occurs
|
||||
if (decryptionPromise.cancel) {
|
||||
decryptionPromise.cancel();
|
||||
}
|
||||
reject(new Error('Decryption timeout'));
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
// Use a separate try-catch for the race
|
||||
let decryptedContent;
|
||||
try {
|
||||
// Race between decryption and timeout
|
||||
decryptedContent = await Promise.race([
|
||||
decryptContent(currentLesson.content),
|
||||
decryptionPromise,
|
||||
timeoutPromise
|
||||
]);
|
||||
|
||||
// Clear the timeout if decryption wins
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
// If timeout or network error, schedule a retry
|
||||
setTimeout(() => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user