in sdk/storage/storage-blob/src/policies/StorageRetryPolicy.ts [179:260]
protected shouldRetry(
isPrimaryRetry: boolean,
attempt: number,
response?: HttpOperationResponse,
err?: RestError,
): boolean {
if (attempt >= this.retryOptions.maxTries!) {
logger.info(
`RetryPolicy: Attempt(s) ${attempt} >= maxTries ${this.retryOptions
.maxTries!}, no further try.`,
);
return false;
}
// Handle network failures, you may need to customize the list when you implement
// your own http client
const retriableErrors = [
"ETIMEDOUT",
"ESOCKETTIMEDOUT",
"ECONNREFUSED",
"ECONNRESET",
"ENOENT",
"ENOTFOUND",
"TIMEOUT",
"EPIPE",
"REQUEST_SEND_ERROR", // For default xhr based http client provided in ms-rest-js
];
if (err) {
for (const retriableError of retriableErrors) {
if (
err.name.toUpperCase().includes(retriableError) ||
err.message.toUpperCase().includes(retriableError) ||
(err.code && err.code.toString().toUpperCase() === retriableError)
) {
logger.info(`RetryPolicy: Network error ${retriableError} found, will retry.`);
return true;
}
}
}
// If attempt was against the secondary & it returned a StatusNotFound (404), then
// the resource was not found. This may be due to replication delay. So, in this
// case, we'll never try the secondary again for this operation.
if (response || err) {
const statusCode = response ? response.status : err ? err.statusCode : 0;
if (!isPrimaryRetry && statusCode === 404) {
logger.info(`RetryPolicy: Secondary access with 404, will retry.`);
return true;
}
// Server internal error or server timeout
if (statusCode === 503 || statusCode === 500) {
logger.info(`RetryPolicy: Will retry for status code ${statusCode}.`);
return true;
}
}
// [Copy source error code] Feature is pending on service side, skip retry on copy source error for now.
// if (response) {
// // Retry select Copy Source Error Codes.
// if (response?.status >= 400) {
// const copySourceError = response.headers.get(HeaderConstants.X_MS_CopySourceErrorCode);
// if (copySourceError !== undefined) {
// switch (copySourceError) {
// case "InternalError":
// case "OperationTimedOut":
// case "ServerBusy":
// return true;
// }
// }
// }
// }
if (err?.code === "PARSE_ERROR" && err?.message.startsWith(`Error "Error: Unclosed root tag`)) {
logger.info(
"RetryPolicy: Incomplete XML response likely due to service timeout, will retry.",
);
return true;
}
return false;
}