Skip to content

Commit f54e65b

Browse files
authored
Add error handling delay in load function (#35)
1 parent e829207 commit f54e65b

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"dev": "rollup --config --watch",
2626
"lint": "eslint src/ test/",
2727
"fix-lint": "eslint src/ test/ --fix",
28-
"test": "mocha out/test/*.test.{js,cjs,mjs} --timeout 10000"
28+
"test": "mocha out/test/*.test.{js,cjs,mjs} --timeout 15000"
2929
},
3030
"repository": {
3131
"type": "git",

src/load.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { AzureAppConfigurationImpl } from "./AzureAppConfigurationImpl";
88
import { AzureAppConfigurationOptions, MaxRetries, MaxRetryDelayInMs } from "./AzureAppConfigurationOptions";
99
import * as RequestTracing from "./requestTracing/constants";
1010

11+
const MinDelayForUnhandedError: number = 5000; // 5 seconds
12+
1113
/**
1214
* Loads the data from Azure App Configuration service and returns an instance of AzureAppConfiguration.
1315
* @param connectionString The connection string for the App Configuration store.
@@ -26,8 +28,11 @@ export async function load(
2628
credentialOrOptions?: TokenCredential | AzureAppConfigurationOptions,
2729
appConfigOptions?: AzureAppConfigurationOptions
2830
): Promise<AzureAppConfiguration> {
31+
const startTimestamp = Date.now();
2932
let client: AppConfigurationClient;
3033
let options: AzureAppConfigurationOptions | undefined;
34+
35+
// input validation
3136
if (typeof connectionStringOrEndpoint === "string" && !instanceOfTokenCredential(credentialOrOptions)) {
3237
const connectionString = connectionStringOrEndpoint;
3338
options = credentialOrOptions as AzureAppConfigurationOptions;
@@ -55,9 +60,20 @@ export async function load(
5560
throw new Error("A connection string or an endpoint with credential must be specified to create a client.");
5661
}
5762

58-
const appConfiguration = new AzureAppConfigurationImpl(client, options);
59-
await appConfiguration.load();
60-
return appConfiguration;
63+
try {
64+
const appConfiguration = new AzureAppConfigurationImpl(client, options);
65+
await appConfiguration.load();
66+
return appConfiguration;
67+
} catch (error) {
68+
// load() method is called in the application's startup code path.
69+
// Unhandled exceptions cause application crash which can result in crash loops as orchestrators attempt to restart the application.
70+
// Knowing the intended usage of the provider in startup code path, we mitigate back-to-back crash loops from overloading the server with requests by waiting a minimum time to propagate fatal errors.
71+
const delay = MinDelayForUnhandedError - (Date.now() - startTimestamp);
72+
if (delay > 0) {
73+
await new Promise((resolve) => setTimeout(resolve, delay));
74+
}
75+
throw error;
76+
}
6177
}
6278

6379
function instanceOfTokenCredential(obj: unknown) {

0 commit comments

Comments
 (0)