4const transientMsgRe = /ETIMEDOUT|ECONNRESET|ECONNREFUSED|ENOTFOUND|socket hang up|timeout|terminated|429|500|502|503|504/ 6export const isTransientKubeErr = (err: any): boolean => { 7 if (err?.name === 'AbortError') return true 8 const msg = String(err?.message || err?.body || err) 9 return transientMsgRe.test(msg) 12export const withKubeRetry = async <T,>(fn: () => Promise<T>, cluster_name: string): Promise<T> => { 14 const maxRetries = 2, baseDelayMs = 1000 15 for (let attempt = 0; ; attempt++) { 19 if (!isTransientKubeErr(err) || attempt >= maxRetries) throw err 20 await sleep(baseDelayMs * 2 ** attempt)