I have a problem where sometimes the 3rd party API I am accessing via FETCH times out, but only after 300 seconds.
Because this is the same time as the CC time limit, what happens is my CC tasks errors because it runs out of time and then automatically retries itself, which takes another 5 minutes only to error again. And as such it goes into a horrible 5 min error retry spiral.
Is there a way that I can force the fetch call to finish when I see that it is taking way longer than usual to complete?
Yes, you can solve this using an AbortController, and passing in an abort signal into the fetch call as an additional parameter.
Something like this
import { TaskContext } from '@journeyapps/cloudcode';
export async function run(this: TaskContext) {
// Your code here
const AbortController = globalThis.AbortController
const controller = new AbortController();
let abortSource: string;
// have the beforeTimeout warning trigger the AbortController
this.on('beforeTimeout', (params) => {
console.log(`in beforeTimeout: Triggering abort controller: Params`, params)
abortSource = 'beforeTimeout';
// this line sends the abort signal
controller.abort();
console.log('After calling abort');
});
// manually trigger the AbortController after a specific period of time, e.g. 3 mins
const timeout = setTimeout(() => {
console.log('Triggering the abort controller');
abortSource = 'manualTimeout';
// this line sends the abort signal
controller.abort();
}, 3*60*1000);
const url = 'http://example.com';
// here we are passing in the additional fetch param 'signal' to handle our abort signal
const config = {
method: 'GET',
signal: controller.signal
}
console.log(`About to fetch`);
try {
let result = await fetch(url, config);
if (result.ok) {
console.log(`Result ok`);
let response = await result.text();
console.log(`Response: ${response}`);
} else {
console.log(`Result not ok`);
console.log(`Result status: ${result.status}`)
console.log(`Result statusText: ${result.statusText}`)
}
} catch (er) {
console.log(`Error: ${er.name}`);
if (er.name === 'AbortError') {
console.log(`Fetch request was aborted by: ${abortSource}`);
}
}
console.log('All done ')
clearTimeout(timeout);
return true;
}