{"record":{"id":"04b39ed13fccb2f8","repo":"nilaoda/N_m3u8DL-RE","slug":"failed-to-execute-action-after-maxretries-retries","errorCode":null,"errorMessage":"Failed to execute action after {maxRetries} retries.","messagePattern":"Failed to execute action after (.+?) retries\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/N_m3u8DL-RE.Common/Util/RetryUtil.cs","lineNumber":33,"sourceCode":"        while (retryCount < maxRetries)\n        {\n            try\n            {\n                result = await funcAsync();\n                break;\n            }\n            catch (Exception ex) when (ex is WebException or IOException or HttpRequestException)\n            {\n                currentException = ex;\n                retryCount++;\n                Logger.WarnMarkUp($\"[grey]{ex.Message.EscapeMarkup()} ({retryCount}/{maxRetries})[/]\");\n                await Task.Delay(retryDelayMilliseconds + (retryDelayIncrementMilliseconds * (retryCount - 1)));\n            }\n        }\n\n        if (retryCount == maxRetries)\n        {\n            throw new Exception($\"Failed to execute action after {maxRetries} retries.\", currentException);\n        }\n\n        return result;\n    }\n}","sourceCodeStart":15,"sourceCodeEnd":38,"githubUrl":"https://github.com/nilaoda/N_m3u8DL-RE/blob/e113dee70c924ee08dae5460624909b04d84cb76/src/N_m3u8DL-RE.Common/Util/RetryUtil.cs#L15-L38","documentation":"WebRequestRetryAsync exhausts all retry attempts for the supplied action and still has no successful result, so it gives up and throws, wrapping the last underlying exception as InnerException. It exists so callers get one clear, self-describing failure after retries instead of a silent loop.","triggerScenarios":"Calling WebRequestRetryAsync with an action (typically an HTTP request) that keeps throwing (network failure, 5xx, timeout) for maxRetries consecutive attempts; after each failure it delays retryDelayMilliseconds plus the linear backoff increment.","commonSituations":"Remote server or CDN down/slow, flaky network or DNS, rate limiting returning 503, TLS/proxy problems, or maxRetries configured too low for a slow endpoint.","solutions":["Inspect the InnerException (currentException) to find the real root cause — the wrapper message only says retries ran out.","Increase maxRetries and/or retryDelayMilliseconds/retryDelayIncrementMilliseconds to tolerate transient outages.","Check network connectivity, proxy settings and the target server's health before retrying the operation.","For persistent 4xx/5xx responses, fix the request itself (URL, auth, headers) rather than retrying."],"exampleFix":"// before\nvar data = await RetryUtil.WebRequestRetryAsync(() => DownloadAsync(url), maxRetries: 2);\n\n// after\ntry\n{\n    var data = await RetryUtil.WebRequestRetryAsync(() => DownloadAsync(url), maxRetries: 5, retryDelayMilliseconds: 1000, retryDelayIncrementMilliseconds: 500);\n}\ncatch (Exception ex)\n{\n    Log.Error(ex.InnerException, \"Download failed after all retries\");\n    throw;\n}","handlingStrategy":"retry","validationCode":"using var ping = new HttpClient();\nvar ok = (await ping.GetAsync(url)).IsSuccessStatusCode;\nif (!ok) throw new HttpRequestException(\"Endpoint unhealthy before starting retry loop\");","typeGuard":null,"tryCatchPattern":"try\n{\n    result = await RetryUtil.WebRequestRetryAsync(action, maxRetries, retryDelayMilliseconds);\n}\ncatch (Exception ex)\n{\n    var root = ex.InnerException ?? ex; // real cause\n    Log.Error(root, \"All {Retries} attempts failed\", maxRetries);\n}","preventionTips":["Always log InnerException — the wrapper message hides the root cause.","Size maxRetries and backoff to the endpoint's known reliability.","Check server/network health before launching long retry loops."],"tags":["network","retry","http"],"backgroundTag":"request-timeout","analyzedSha":"e113dee70c924ee08dae5460624909b04d84cb76","analyzedAt":"2026-09-13T02:43:21.078Z","contentChangedAt":"2026-09-13T02:43:21.078Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}