wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
 
import {
    Constants,
    INetworkModule,
    Logger,
    NetworkRequestOptions,
    NetworkResponse,
} from "@azure/msal-common/node";
import { IHttpRetryPolicy } from "../retry/IHttpRetryPolicy.js";
import { HttpMethod } from "../utils/Constants.js";
 
export class HttpClientWithRetries implements INetworkModule {
    private httpClientNoRetries: INetworkModule;
    private retryPolicy: IHttpRetryPolicy;
    private logger: Logger;
 
    constructor(
        httpClientNoRetries: INetworkModule,
        retryPolicy: IHttpRetryPolicy,
        logger: Logger
    ) {
        this.httpClientNoRetries = httpClientNoRetries;
        this.retryPolicy = retryPolicy;
        this.logger = logger;
    }
 
    private async sendNetworkRequestAsyncHelper<T>(
        httpMethod: HttpMethod,
        url: string,
        options?: NetworkRequestOptions
    ): Promise<NetworkResponse<T>> {
        if (httpMethod === HttpMethod.GET) {
            return this.httpClientNoRetries.sendGetRequestAsync(url, options);
        } else {
            return this.httpClientNoRetries.sendPostRequestAsync(url, options);
        }
    }
 
    private async sendNetworkRequestAsync<T>(
        httpMethod: HttpMethod,
        url: string,
        options?: NetworkRequestOptions
    ): Promise<NetworkResponse<T>> {
        // the underlying network module (custom or HttpClient) will make the call
        let response: NetworkResponse<T> =
            await this.sendNetworkRequestAsyncHelper(httpMethod, url, options);
 
        if ("isNewRequest" in this.retryPolicy) {
            this.retryPolicy.isNewRequest = true;
        }
 
        let currentRetry: number = 0;
        while (
            await this.retryPolicy.pauseForRetry(
                response.status,
                currentRetry,
                this.logger,
                response.headers[Constants.HeaderNames.RETRY_AFTER]
            )
        ) {
            response = await this.sendNetworkRequestAsyncHelper(
                httpMethod,
                url,
                options
            );
            currentRetry++;
        }
 
        return response;
    }
 
    public async sendGetRequestAsync<T>(
        url: string,
        options?: NetworkRequestOptions
    ): Promise<NetworkResponse<T>> {
        return this.sendNetworkRequestAsync(HttpMethod.GET, url, options);
    }
 
    public async sendPostRequestAsync<T>(
        url: string,
        options?: NetworkRequestOptions
    ): Promise<NetworkResponse<T>> {
        return this.sendNetworkRequestAsync(HttpMethod.POST, url, options);
    }
}