Skip to content

Commit 009ccd5

Browse files
update
1 parent 80108c9 commit 009ccd5

File tree

6 files changed

+18
-33
lines changed

6 files changed

+18
-33
lines changed

src/AzureAppConfigurationImpl.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { FeatureFlagTracingOptions } from "./requestTracing/FeatureFlagTracingOp
3434
import { KeyFilter, LabelFilter, SettingSelector } from "./types.js";
3535
import { ConfigurationClientManager } from "./ConfigurationClientManager.js";
3636
import { getFixedBackoffDuration, calculateBackoffDuration } from "./failover.js";
37-
import { OperationError, ArgumentError, isFailoverableError, isRetriableError, isInstantlyThrowError } from "./error.js";
37+
import { InvalidOperationError, ArgumentError, isFailoverableError, isRetriableError, isArgumentError } from "./error.js";
3838

3939
const MIN_DELAY_FOR_UNHANDLED_FAILURE = 5_000; // 5 seconds
4040

@@ -247,7 +247,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
247247
})
248248
]);
249249
} catch (error) {
250-
if (!isInstantlyThrowError(error)) {
250+
if (!isArgumentError(error)) {
251251
const timeElapsed = Date.now() - startTimestamp;
252252
if (timeElapsed < MIN_DELAY_FOR_UNHANDLED_FAILURE) {
253253
// load() method is called in the application's startup code path.
@@ -282,22 +282,22 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
282282
const segment = segments[i];
283283
// undefined or empty string
284284
if (!segment) {
285-
throw new OperationError(`Failed to construct configuration object: Invalid key: ${key}`);
285+
throw new InvalidOperationError(`Failed to construct configuration object: Invalid key: ${key}`);
286286
}
287287
// create path if not exist
288288
if (current[segment] === undefined) {
289289
current[segment] = {};
290290
}
291291
// The path has been occupied by a non-object value, causing ambiguity.
292292
if (typeof current[segment] !== "object") {
293-
throw new OperationError(`Ambiguity occurs when constructing configuration object from key '${key}', value '${value}'. The path '${segments.slice(0, i + 1).join(separator)}' has been occupied.`);
293+
throw new InvalidOperationError(`Ambiguity occurs when constructing configuration object from key '${key}', value '${value}'. The path '${segments.slice(0, i + 1).join(separator)}' has been occupied.`);
294294
}
295295
current = current[segment];
296296
}
297297

298298
const lastSegment = segments[segments.length - 1];
299299
if (current[lastSegment] !== undefined) {
300-
throw new OperationError(`Ambiguity occurs when constructing configuration object from key '${key}', value '${value}'. The key should not be part of another key.`);
300+
throw new InvalidOperationError(`Ambiguity occurs when constructing configuration object from key '${key}', value '${value}'. The key should not be part of another key.`);
301301
}
302302
// set value to the last segment
303303
current[lastSegment] = value;
@@ -310,7 +310,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
310310
*/
311311
async refresh(): Promise<void> {
312312
if (!this.#refreshEnabled && !this.#featureFlagRefreshEnabled) {
313-
throw new OperationError("Refresh is not enabled for key-values or feature flags.");
313+
throw new InvalidOperationError("Refresh is not enabled for key-values or feature flags.");
314314
}
315315

316316
if (this.#refreshInProgress) {
@@ -329,7 +329,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
329329
*/
330330
onRefresh(listener: () => any, thisArg?: any): Disposable {
331331
if (!this.#refreshEnabled && !this.#featureFlagRefreshEnabled) {
332-
throw new OperationError("Refresh is not enabled for key-values or feature flags.");
332+
throw new InvalidOperationError("Refresh is not enabled for key-values or feature flags.");
333333
}
334334

335335
const boundedListener = listener.bind(thisArg);

src/ConfigurationClientManager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { TokenCredential } from "@azure/identity";
77
import { AzureAppConfigurationOptions } from "./AzureAppConfigurationOptions.js";
88
import { isBrowser, isWebWorker } from "./requestTracing/utils.js";
99
import * as RequestTracing from "./requestTracing/constants.js";
10-
import { instanceOfTokenCredential, shuffleList, getEndpointUrl } from "./common/utils.js";
10+
import { instanceOfTokenCredential, shuffleList } from "./common/utils.js";
1111
import { ArgumentError } from "./error.js";
1212

1313
// Configuration client retry options
@@ -61,7 +61,7 @@ export class ConfigurationClientManager {
6161
const regexMatch = connectionString.match(ConnectionStringRegex);
6262
if (regexMatch) {
6363
const endpointFromConnectionStr = regexMatch[1];
64-
this.endpoint = getEndpointUrl(endpointFromConnectionStr);
64+
this.endpoint = new URL(endpointFromConnectionStr);
6565
this.#id = regexMatch[2];
6666
this.#secret = regexMatch[3];
6767
} else {
@@ -72,7 +72,7 @@ export class ConfigurationClientManager {
7272
let endpoint = connectionStringOrEndpoint;
7373
// ensure string is a valid URL.
7474
if (typeof endpoint === "string") {
75-
endpoint = getEndpointUrl(endpoint);
75+
endpoint = new URL(endpoint);
7676
}
7777

7878
const credential = credentialOrOptions as TokenCredential;

src/common/utils.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,6 @@ export function shuffleList<T>(array: T[]): T[] {
99
return array;
1010
}
1111

12-
export function getEndpointUrl(endpoint: string): URL {
13-
try {
14-
return new URL(endpoint);
15-
} catch (error) {
16-
throw new TypeError(`Invalid Endpoint URL: ${endpoint}`);
17-
}
18-
}
19-
20-
export function getUrlHost(url: string): string {
21-
return new URL(url).host;
22-
}
23-
2412
export function instanceOfTokenCredential(obj: unknown) {
2513
return obj && typeof obj === "object" && "getToken" in obj && typeof obj.getToken === "function";
2614
}

src/error.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import { isRestError } from "@azure/core-rest-pipeline";
66
/**
77
* Error thrown when an operation cannot be performed by the Azure App Configuration provider.
88
*/
9-
export class OperationError extends Error {
9+
export class InvalidOperationError extends Error {
1010
constructor(message: string) {
1111
super(message);
12-
this.name = "OperationError";
12+
this.name = "InvalidOperationError";
1313
}
1414
}
1515

@@ -38,7 +38,7 @@ export function isFailoverableError(error: any): boolean {
3838
return false;
3939
}
4040
// ENOTFOUND: DNS lookup failed, ENOENT: no such file or directory
41-
if (error.code == "ENOTFOUND" || error.code === "ENOENT") {
41+
if (error.code === "ENOTFOUND" || error.code === "ENOENT") {
4242
return true;
4343
}
4444
// 401 Unauthorized, 403 Forbidden, 408 Request Timeout, 429 Too Many Requests, 5xx Server Errors
@@ -51,16 +51,14 @@ export function isFailoverableError(error: any): boolean {
5151
}
5252

5353
export function isRetriableError(error: any): boolean {
54-
if (error instanceof ArgumentError ||
55-
error instanceof OperationError ||
56-
error instanceof TypeError ||
54+
if (isArgumentError(error) ||
5755
error instanceof RangeError) {
5856
return false;
5957
}
6058
return true;
6159
}
6260

63-
export function isInstantlyThrowError(error: any): boolean {
61+
export function isArgumentError(error: any): boolean {
6462
if (error instanceof ArgumentError ||
6563
error instanceof TypeError ||
6664
error instanceof RangeError) {

src/failover.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const MIN_BACKOFF_DURATION = 30_000; // 30 seconds in milliseconds
55
const MAX_BACKOFF_DURATION = 10 * 60 * 1000; // 10 minutes in milliseconds
66
const JITTER_RATIO = 0.25;
77

8-
// The backoff duration algorithm is consistent with the .NET configuration provider's implementation.
98
export function getFixedBackoffDuration(timeElapsed: number): number | undefined {
109
if (timeElapsed <= 100_000) { // 100 seconds in milliseconds
1110
return 5_000; // 5 seconds in milliseconds

src/keyvault/AzureKeyVaultKeyValueAdapter.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
import { ConfigurationSetting, isSecretReference, parseSecretReference } from "@azure/app-configuration";
55
import { IKeyValueAdapter } from "../IKeyValueAdapter.js";
66
import { KeyVaultOptions } from "./KeyVaultOptions.js";
7-
import { getUrlHost } from "../common/utils.js";
87
import { ArgumentError, KeyVaultReferenceError } from "../error.js";
98
import { SecretClient, parseKeyVaultSecretIdentifier } from "@azure/keyvault-secrets";
109

1110
export class AzureKeyVaultKeyValueAdapter implements IKeyValueAdapter {
1211
/**
1312
* Map vault hostname to corresponding secret client.
14-
*/
13+
*/
1514
#secretClients: Map<string, SecretClient>;
1615
#keyVaultOptions: KeyVaultOptions | undefined;
1716

@@ -59,7 +58,8 @@ export class AzureKeyVaultKeyValueAdapter implements IKeyValueAdapter {
5958
if (this.#secretClients === undefined) {
6059
this.#secretClients = new Map();
6160
for (const client of this.#keyVaultOptions?.secretClients ?? []) {
62-
this.#secretClients.set(getUrlHost(client.vaultUrl), client);
61+
const clientUrl = new URL(client.vaultUrl);
62+
this.#secretClients.set(clientUrl.host, client);
6363
}
6464
}
6565

0 commit comments

Comments
 (0)