summaryrefslogtreecommitdiff
path: root/packages/web-util/src/context/bank-api.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/web-util/src/context/bank-api.ts')
-rw-r--r--packages/web-util/src/context/bank-api.ts77
1 files changed, 50 insertions, 27 deletions
diff --git a/packages/web-util/src/context/bank-api.ts b/packages/web-util/src/context/bank-api.ts
index bd0653451..3f6a32f4b 100644
--- a/packages/web-util/src/context/bank-api.ts
+++ b/packages/web-util/src/context/bank-api.ts
@@ -25,7 +25,7 @@ import {
TalerCoreBankCacheEviction,
TalerCoreBankHttpClient,
TalerCorebankApi,
- TalerError
+ TalerError,
} from "@gnu-taler/taler-util";
import {
ComponentChildren,
@@ -35,7 +35,7 @@ import {
h,
} from "preact";
import { useContext, useEffect, useState } from "preact/hooks";
-import { APIClient, ActiviyTracker, BankLib, Suscriber } from "./activity.js";
+import { APIClient, ActiviyTracker, BankLib, Subscriber } from "./activity.js";
import { useTranslationContext } from "./translation.js";
import { BrowserFetchHttpLib, ErrorLoading } from "../index.browser.js";
@@ -49,14 +49,15 @@ export type BankContextType = {
config: TalerCorebankApi.Config;
lib: BankLib;
hints: VersionHint[];
- onActivity: Suscriber<ObservabilityEvent>;
+ onActivity: Subscriber<ObservabilityEvent>;
cancelRequest: (eventId: string) => void;
};
// @ts-expect-error default value to undefined, should it be another thing?
const BankContext = createContext<BankContextType>(undefined);
-export const useBankCoreApiContext = (): BankContextType => useContext(BankContext);
+export const useBankCoreApiContext = (): BankContextType =>
+ useContext(BankContext);
enum VersionHint {
NONE,
@@ -65,7 +66,7 @@ enum VersionHint {
type Evictors = {
conversion?: CacheEvictor<TalerBankConversionCacheEviction>;
bank?: CacheEvictor<TalerCoreBankCacheEviction>;
-}
+};
type ConfigResult<T> =
| undefined
@@ -73,6 +74,8 @@ type ConfigResult<T> =
| { type: "incompatible"; result: T; supported: string }
| { type: "error"; error: TalerError };
+const CONFIG_FAIL_TRY_AGAIN_MS = 5000;
+
export const BankApiProvider = ({
baseUrl,
children,
@@ -81,17 +84,21 @@ export const BankApiProvider = ({
}: {
baseUrl: URL;
children: ComponentChildren;
- evictors?: Evictors,
+ evictors?: Evictors;
frameOnError: FunctionComponent<{ children: ComponentChildren }>;
}): VNode => {
- const [checked, setChecked] = useState<ConfigResult<TalerCorebankApi.Config>>();
+ const [checked, setChecked] =
+ useState<ConfigResult<TalerCorebankApi.Config>>();
const { i18n } = useTranslationContext();
- const { getRemoteConfig, VERSION, lib, cancelRequest, onActivity } = buildBankApiClient(baseUrl, evictors);
+ const { getRemoteConfig, VERSION, lib, cancelRequest, onActivity } =
+ buildBankApiClient(baseUrl, evictors);
useEffect(() => {
- getRemoteConfig()
- .then((config) => {
+ let keepRetrying = true;
+ async function testConfig(): Promise<void> {
+ try {
+ const config = await getRemoteConfig();
if (LibtoolVersion.compare(VERSION, config.version)) {
setChecked({ type: "ok", config, hints: [] });
} else {
@@ -101,16 +108,30 @@ export const BankApiProvider = ({
supported: VERSION,
});
}
- })
- .catch((error: unknown) => {
+ } catch (error) {
if (error instanceof TalerError) {
+ if (keepRetrying) {
+ setTimeout(() => {
+ testConfig();
+ }, CONFIG_FAIL_TRY_AGAIN_MS);
+ }
setChecked({ type: "error", error });
+ } else {
+ setChecked({ type: "error", error: TalerError.fromException(error) });
}
- });
+ }
+ }
+ testConfig();
+ return () => {
+ // on unload, stop retry
+ keepRetrying = false;
+ };
}, []);
if (checked === undefined) {
- return h(frameOnError, { children: h("div", {}, "checking compatibility with server...") });
+ return h(frameOnError, {
+ children: h("div", {}, "checking compatibility with server..."),
+ });
}
if (checked.type === "error") {
return h(frameOnError, {
@@ -141,7 +162,9 @@ export const BankApiProvider = ({
});
};
-function buildBankApiClient(url: URL, evictors: Evictors,
+function buildBankApiClient(
+ url: URL,
+ evictors: Evictors,
): APIClient<BankLib, TalerCorebankApi.Config> {
const httpFetch = new BrowserFetchHttpLib({
enableThrottling: true,
@@ -154,11 +177,7 @@ function buildBankApiClient(url: URL, evictors: Evictors,
},
});
- const bank = new TalerCoreBankHttpClient(
- url.href,
- httpLib,
- evictors.bank,
- );
+ const bank = new TalerCoreBankHttpClient(url.href, httpLib, evictors.bank);
const conversion = new TalerBankConversionHttpClient(
bank.getConversionInfoAPI().href,
httpLib,
@@ -170,32 +189,36 @@ function buildBankApiClient(url: URL, evictors: Evictors,
httpLib,
);
- async function getRemoteConfig() {
- const resp = await bank.getConfig()
- return resp.body
+ async function getRemoteConfig(): Promise<TalerCorebankApi.Config> {
+ const resp = await bank.getConfig();
+ if (resp.type === "fail") {
+ throw TalerError.fromUncheckedDetail(resp.detail);
+ }
+ return resp.body;
}
return {
getRemoteConfig,
VERSION: bank.PROTOCOL_VERSION,
lib: {
- bank, conversion, auth
+ bank,
+ conversion,
+ auth,
},
onActivity: tracker.subscribe,
cancelRequest: httpLib.cancelRequest,
};
}
-
export const BankApiProviderTesting = ({
children,
value,
}: {
- value: BankContextType
+ value: BankContextType;
children: ComponentChildren;
}): VNode => {
return h(BankContext.Provider, {
value,
children,
});
-}
+};