Skip to content

Commit c89e075

Browse files
authored
feat: UI landing page for when DB is empty (#278)
1 parent 3f7af02 commit c89e075

File tree

4 files changed

+105
-67
lines changed

4 files changed

+105
-67
lines changed

packages/error-middleware/src/middleware.ts

+12
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ export const createErrorMiddleware = (logger: Logger): ErrorRequestHandler => {
1616
return;
1717
}
1818

19+
if (
20+
err instanceof Error &&
21+
err.message === "CACHE_ERROR: latest height not found"
22+
) {
23+
res
24+
.status(500)
25+
.send(
26+
"Aztec indexer has not been able to index any blocks from chain yet"
27+
);
28+
return;
29+
}
30+
1931
if (err instanceof Error) {
2032
logger.error(
2133
`Error-handler: name: ${err.name}, message: ${err.message} (for route: ${_req.originalUrl})`

services/explorer-ui/src/api/client.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class ApiError extends Error {
1818
) {
1919
super(message);
2020
this.name = "ApiError";
21+
this.status = status;
2122
}
2223
}
2324

@@ -34,9 +35,18 @@ client.interceptors.response.use(
3435
},
3536
(error: AxiosError) => {
3637
if (error.response) {
38+
let errorString = error.response.statusText;
39+
try {
40+
errorString =
41+
typeof error.response.data === "string"
42+
? error.response.data
43+
: JSON.stringify(error.response.data);
44+
} catch {
45+
// ignore
46+
}
3747
lastError = {
3848
date: new Date(),
39-
error: new ApiError(error.response.status, "An error occurred", "API"),
49+
error: new ApiError(error.response.status, errorString, "API"),
4050
};
4151
} else if (error.request) {
4252
lastError = {

services/explorer-ui/src/hooks/system-health.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,24 @@ const evaluateHealth = ({
2929
lastSuccessfulRequest: { date: Date; path: string } | null;
3030
lastError: {
3131
date: Date;
32-
error: { type: "API" | "Schema"; message: string };
32+
error: { type: "API" | "Schema"; status: number; message: string };
3333
} | null;
3434
chainErrors: ChicmozL2RpcNodeError[] | undefined;
3535
}): EvaluatedHealth => {
36+
// TODO: this should return an array with all evaluation-results
3637
const reasonableTimeStamp = Date.now() - REASONABLE_API_LIVENESS_TIME;
3738

38-
if (!lastSuccessfulRequest) {
39+
if (!lastSuccessfulRequest && lastError) {
3940
return {
4041
health: SystemHealthStatus.DOWN,
41-
reason: "No successful API requests has been made",
42+
reason: `${lastError?.error.status} - ${lastError?.error.message}`,
4243
};
4344
}
4445

45-
if (lastError?.error.message === "No response received from server") {
46+
if (!lastSuccessfulRequest) {
4647
return {
4748
health: SystemHealthStatus.DOWN,
48-
reason: "No response received from server",
49+
reason: "No successful requests have been made",
4950
};
5051
}
5152

@@ -108,7 +109,7 @@ export const useSystemHealth = () => {
108109
} | null>(null);
109110
const [lastError, setLastError] = useState<{
110111
date: Date;
111-
error: { type: "API" | "Schema"; message: string };
112+
error: { type: "API" | "Schema"; message: string; status: number };
112113
} | null>(null);
113114
const { data: chainErrors } = useChainErrors();
114115

services/explorer-ui/src/pages/landing/index.tsx

+75-60
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import { InfoBadge } from "~/components/info-badge";
44
import { type TxEffectTableSchema } from "~/components/tx-effects/tx-effects-schema";
55
import { TxEffectsTable } from "~/components/tx-effects/tx-effects-table";
66
import {
7+
SystemHealthStatus,
78
useAvarageBlockTime,
89
useAvarageFees,
910
useGetTxEffectsByBlockHeightRange,
1011
useLatestBlocks,
1112
usePendingTxs,
1213
useSubTitle,
14+
useSystemHealth,
1315
useTotalContracts,
1416
useTotalContractsLast24h,
1517
useTotalTxEffects,
@@ -20,6 +22,7 @@ import { routes } from "~/routes/__root";
2022
import { mapLatestBlocks, parseTxEffectsData } from "./util";
2123

2224
export const Landing: FC = () => {
25+
const { systemHealth } = useSystemHealth();
2326
const { data: latestBlocks, isLoading, error } = useLatestBlocks();
2427
const {
2528
data: totalTxEffects,
@@ -92,67 +95,79 @@ export const Landing: FC = () => {
9295

9396
return (
9497
<div className="mx-auto px-5 max-w-[1440px] md:px-[70px]">
95-
<div className="hidden md:mt-16 md:flex flex-wrap justify-center my-20">
96-
<h1 className="">Explore the power of privacy on Aztec</h1>
97-
</div>
98-
<div className="grid grid-cols-2 gap-3 my-20 md:grid-cols-3 md:gap-5">
99-
<InfoBadge
100-
title="Total transactions"
101-
isLoading={loadingTotalEffects}
102-
error={errorTotalEffects}
103-
data={totalTxEffects}
104-
/>
105-
<InfoBadge
106-
title="Total Contract Classes"
107-
isLoading={loadingAmountContracts}
108-
error={errorAmountContracts}
109-
data={totalAmountOfContracts}
110-
/>
111-
<InfoBadge
112-
title={`Average fees (${formattedFees.denomination} FPA)`}
113-
isLoading={loadingAvarageFees}
114-
error={errorAvarageFees}
115-
data={formattedFees.value}
116-
/>
117-
<InfoBadge
118-
title="Total transactions last 24h"
119-
isLoading={loadingTotalEffects24h}
120-
error={errorTotalEffects24h}
121-
data={totalTxEffects24h}
122-
/>
123-
<InfoBadge
124-
title="Total Contract Classes last 24h"
125-
isLoading={loadingAmountContracts24h}
126-
error={errorAmountContracts24h}
127-
data={totalAmountOfContracts24h}
128-
/>
129-
<InfoBadge
130-
title="Average block time"
131-
isLoading={loadingAvarageBlockTime}
132-
error={errorAvarageBlockTime}
133-
data={averageBlockTimeFormatted}
134-
/>
135-
</div>
136-
<div className="flex flex-col gap-4 md:flex-row">
137-
<div className="bg-white rounded-lg shadow-lg w-full md:w-1/2">
138-
<BlocksTable
139-
title="Latest Blocks"
140-
blocks={mapLatestBlocks(latestBlocks)}
141-
isLoading={isLoading}
142-
error={error}
143-
disableSizeSelector={true}
144-
/>
98+
{systemHealth.health === SystemHealthStatus.DOWN && (
99+
<div className="flex flex-col bg-white w-full h-96 justify-between rounded-lg shadow-md mt-20">
100+
<div className="flex flex-col items-center justify-center h-full">
101+
<h3>System is down</h3>
102+
<p>{systemHealth.reason ?? "No reason provided"}</p>
103+
</div>
145104
</div>
146-
<div className="bg-white rounded-lg shadow-lg w-full md:w-1/2">
147-
<TxEffectsTable
148-
title="Latest TX-Effects"
149-
txEffects={latestTxEffectsWithPending}
150-
isLoading={isLoadingTxEffects}
151-
error={txEffectsError}
152-
disableSizeSelector={true}
153-
/>
154-
</div>
155-
</div>
105+
)}
106+
{systemHealth.health !== SystemHealthStatus.DOWN && (
107+
<>
108+
<div className="hidden md:mt-16 md:flex flex-wrap justify-center my-20">
109+
<h1 className="">Explore the power of privacy on Aztec</h1>
110+
</div>
111+
<div className="grid grid-cols-2 gap-3 my-20 md:grid-cols-3 md:gap-5">
112+
<InfoBadge
113+
title="Total transactions"
114+
isLoading={loadingTotalEffects}
115+
error={errorTotalEffects}
116+
data={totalTxEffects}
117+
/>
118+
<InfoBadge
119+
title="Total Contract Classes"
120+
isLoading={loadingAmountContracts}
121+
error={errorAmountContracts}
122+
data={totalAmountOfContracts}
123+
/>
124+
<InfoBadge
125+
title={`Average fees (${formattedFees.denomination} FPA)`}
126+
isLoading={loadingAvarageFees}
127+
error={errorAvarageFees}
128+
data={formattedFees.value}
129+
/>
130+
<InfoBadge
131+
title="Total transactions last 24h"
132+
isLoading={loadingTotalEffects24h}
133+
error={errorTotalEffects24h}
134+
data={totalTxEffects24h}
135+
/>
136+
<InfoBadge
137+
title="Total Contract Classes last 24h"
138+
isLoading={loadingAmountContracts24h}
139+
error={errorAmountContracts24h}
140+
data={totalAmountOfContracts24h}
141+
/>
142+
<InfoBadge
143+
title="Average block time"
144+
isLoading={loadingAvarageBlockTime}
145+
error={errorAvarageBlockTime}
146+
data={averageBlockTimeFormatted}
147+
/>
148+
</div>
149+
<div className="flex flex-col gap-4 md:flex-row">
150+
<div className="bg-white rounded-lg shadow-lg w-full md:w-1/2">
151+
<BlocksTable
152+
title="Latest Blocks"
153+
blocks={mapLatestBlocks(latestBlocks)}
154+
isLoading={isLoading}
155+
error={error}
156+
disableSizeSelector={true}
157+
/>
158+
</div>
159+
<div className="bg-white rounded-lg shadow-lg w-full md:w-1/2">
160+
<TxEffectsTable
161+
title="Latest TX-Effects"
162+
txEffects={latestTxEffectsWithPending}
163+
isLoading={isLoadingTxEffects}
164+
error={txEffectsError}
165+
disableSizeSelector={true}
166+
/>
167+
</div>
168+
</div>
169+
</>
170+
)}
156171
</div>
157172
);
158173
};

0 commit comments

Comments
 (0)