fix: resilient dashboard loading when ledger API unavailable
Tolerate partial API failures and infer Fineract connected state from health. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,17 +12,25 @@ export type MoneySupply = {
|
||||
M2?: { broadMoney?: string; gl2200?: string; metaFiatPending?: string };
|
||||
};
|
||||
|
||||
async function fetchJson<T>(url: string): Promise<T | null> {
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
return res.ok ? ((await res.json()) as T) : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadMoneySupply(): Promise<MoneySupply | null> {
|
||||
for (const path of ['/public/money-supply', '/money-supply/public', '/health/ledger']) {
|
||||
const res = await fetch(settlementApi(path));
|
||||
if (res.ok) return res.json();
|
||||
const data = await fetchJson<MoneySupply>(settlementApi(path));
|
||||
if (data) return data;
|
||||
}
|
||||
|
||||
const healthRes = await fetch(`${settlementApi('/health')}?ledger=1`);
|
||||
if (healthRes.ok) {
|
||||
const data = (await healthRes.json()) as { moneySupply?: MoneySupply };
|
||||
if (data.moneySupply) return data.moneySupply;
|
||||
}
|
||||
const health = await fetchJson<{ moneySupply?: MoneySupply }>(
|
||||
`${settlementApi('/health')}?ledger=1`,
|
||||
);
|
||||
if (health?.moneySupply) return health.moneySupply;
|
||||
|
||||
const apiKey = import.meta.env.VITE_OMNL_API_KEY;
|
||||
if (!apiKey) return null;
|
||||
@@ -47,17 +55,25 @@ export function useCentralBank() {
|
||||
setError(null);
|
||||
try {
|
||||
const [h, o, m2, mon, ms] = await Promise.all([
|
||||
fetch(settlementApi('/health')).then((r) => r.json()),
|
||||
fetch(settlementApi('/office')).then((r) => r.json()),
|
||||
fetch(settlementApi('/tokens/m2')).then((r) => r.json()),
|
||||
fetch(exchangeApi('/swap/monitor?limit=10')).then((r) => r.json()),
|
||||
fetchJson<Record<string, unknown>>(settlementApi('/health')),
|
||||
fetchJson<Record<string, unknown>>(settlementApi('/office')),
|
||||
fetchJson<{ tokens?: unknown[] }>(settlementApi('/tokens/m2')),
|
||||
fetchJson<Record<string, unknown>>(exchangeApi('/swap/monitor?limit=10')),
|
||||
loadMoneySupply(),
|
||||
]);
|
||||
setHealth(h);
|
||||
setOffice(o);
|
||||
setTokenCount(Array.isArray(m2.tokens) ? m2.tokens.length : 0);
|
||||
setTokenCount(Array.isArray(m2?.tokens) ? m2.tokens.length : 0);
|
||||
setMonitor(mon);
|
||||
setMoneySupply(ms);
|
||||
setMoneySupply(
|
||||
ms ??
|
||||
(h?.status === 'ok'
|
||||
? { fineractConnected: true, fineractLive: false, officeId: 24 }
|
||||
: null),
|
||||
);
|
||||
if (!h && !o) {
|
||||
setError('Settlement middleware unreachable');
|
||||
}
|
||||
} catch (e) {
|
||||
setError(e instanceof Error ? e.message : 'Failed to load central bank data');
|
||||
} finally {
|
||||
|
||||
@@ -10,17 +10,24 @@ export type M2Token = DexToken & {
|
||||
transferableExternal?: boolean;
|
||||
};
|
||||
|
||||
async function fetchJson<T>(url: string): Promise<T | null> {
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
return res.ok ? ((await res.json()) as T) : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadOfficeMoneySupply(): Promise<MoneySupply | null> {
|
||||
for (const path of ['/public/money-supply', '/money-supply/public', '/health/ledger']) {
|
||||
const res = await fetch(settlementApi(path));
|
||||
if (res.ok) return res.json();
|
||||
const data = await fetchJson<MoneySupply>(settlementApi(path));
|
||||
if (data) return data;
|
||||
}
|
||||
const healthRes = await fetch(`${settlementApi('/health')}?ledger=1`);
|
||||
if (healthRes.ok) {
|
||||
const data = (await healthRes.json()) as { moneySupply?: MoneySupply };
|
||||
if (data.moneySupply) return data.moneySupply;
|
||||
}
|
||||
return null;
|
||||
const health = await fetchJson<{ moneySupply?: MoneySupply }>(
|
||||
`${settlementApi('/health')}?ledger=1`,
|
||||
);
|
||||
return health?.moneySupply ?? null;
|
||||
}
|
||||
|
||||
export function useOffice24() {
|
||||
@@ -34,15 +41,20 @@ export function useOffice24() {
|
||||
setLoading(true);
|
||||
try {
|
||||
const [o, t, h, ms] = await Promise.all([
|
||||
fetch(settlementApi('/office')).then((r) => r.json()),
|
||||
fetch(settlementApi('/tokens/m2')).then((r) => r.json()),
|
||||
fetch(exchangeApi('/health')).then((r) => r.json()),
|
||||
fetch(loadOfficeMoneySupply()),
|
||||
fetchJson<Record<string, unknown>>(settlementApi('/office')),
|
||||
fetchJson<{ tokens?: M2Token[] }>(settlementApi('/tokens/m2')),
|
||||
fetchJson<Record<string, unknown>>(exchangeApi('/health')),
|
||||
loadOfficeMoneySupply(),
|
||||
]);
|
||||
setOffice(o);
|
||||
setTokens(Array.isArray(t.tokens) ? t.tokens : []);
|
||||
setTokens(Array.isArray(t?.tokens) ? t.tokens : []);
|
||||
setHealth(h);
|
||||
setMoneySupply(ms);
|
||||
setMoneySupply(
|
||||
ms ??
|
||||
(o
|
||||
? { fineractConnected: true, fineractLive: false, officeId: 24 }
|
||||
: null),
|
||||
);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user