diff options
Diffstat (limited to 'packages/web-util/src/context/bank-api.ts')
-rw-r--r-- | packages/web-util/src/context/bank-api.ts | 77 |
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, }); -} +}; |