Skip to content

Commit 278c20a

Browse files
committed
add error boundaries, fix lazy render of modules and fix padding in Date picker
1 parent 6a41b31 commit 278c20a

File tree

3 files changed

+54
-24
lines changed

3 files changed

+54
-24
lines changed

apps/dashboard/src/@/components/ui/DatePickerWithRange.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ export function DatePickerWithRange(props: {
6969
<DynamicHeight>
7070
<div>
7171
{!isValid && (
72-
<p className="flex items-center justify-center gap-2 pt-2 text-center text-destructive-text text-sm">
72+
<p className="flex items-center justify-center gap-2 py-2 text-center text-destructive-text text-sm">
7373
<CalendarX2Icon className="h-4 w-4" />
7474
Invalid date range
7575
</p>
7676
)}
7777
{props.header}
7878

79-
<div className="px-4">
79+
<div className={cn("px-4", !props.header && "py-4")}>
8080
<TabButtons
8181
tabClassName="!text-sm"
8282
activeTabClassName="!bg-inverted !text-inverted-foreground"

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/module-card.tsx

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ import {
1414
DialogTrigger,
1515
} from "@/components/ui/dialog";
1616
import { Skeleton } from "@/components/ui/skeleton";
17+
import * as Sentry from "@sentry/nextjs";
1718
import { useMutation } from "@tanstack/react-query";
1819
import { TransactionButton } from "components/buttons/TransactionButton";
1920
import { InfoIcon } from "lucide-react";
20-
import { Suspense, useState } from "react";
21+
import { Suspense, useEffect, useState } from "react";
22+
import { ErrorBoundary, type FallbackProps } from "react-error-boundary";
2123
import { toast } from "sonner";
2224
import {
2325
type ContractOptions,
@@ -98,24 +100,30 @@ export function ModuleCard(props: ModuleCardProps) {
98100
return (
99101
<>
100102
<Suspense fallback={<GenericModuleLoadingSkeleton />}>
101-
<ModuleInstance
102-
contract={contract}
103-
contractInfo={{
104-
name: contractInfo.name,
105-
description: contractInfo.description,
106-
publisher: contractInfo.publisher,
107-
version: contractInfo.version,
108-
}}
109-
ownerAccount={ownerAccount}
110-
uninstallButton={{
111-
onClick: () => {
112-
setIsUninstallModalOpen(true);
113-
},
114-
isPending: uninstallMutation.isPending,
115-
}}
116-
moduleAddress={moduleAddress}
117-
allModuleContractInfo={props.allModuleContractInfo}
118-
/>
103+
<ErrorBoundary
104+
FallbackComponent={(p) => (
105+
<ModuleErrorBoundary moduleName={contractInfo.name} {...p} />
106+
)}
107+
>
108+
<ModuleInstance
109+
contract={contract}
110+
contractInfo={{
111+
name: contractInfo.name,
112+
description: contractInfo.description,
113+
publisher: contractInfo.publisher,
114+
version: contractInfo.version,
115+
}}
116+
ownerAccount={ownerAccount}
117+
uninstallButton={{
118+
onClick: () => {
119+
setIsUninstallModalOpen(true);
120+
},
121+
isPending: uninstallMutation.isPending,
122+
}}
123+
moduleAddress={moduleAddress}
124+
allModuleContractInfo={props.allModuleContractInfo}
125+
/>
126+
</ErrorBoundary>
119127
</Suspense>
120128

121129
<Dialog
@@ -303,3 +311,25 @@ export function ModuleCardUI(props: ModuleCardUIProps) {
303311
function GenericModuleLoadingSkeleton() {
304312
return <Skeleton className="h-[190px] w-full border border-border" />;
305313
}
314+
315+
function ModuleErrorBoundary(
316+
props: FallbackProps & {
317+
moduleName: string;
318+
},
319+
) {
320+
// eslint-disable-next-line no-restricted-syntax
321+
useEffect(() => {
322+
Sentry.withScope((scope) => {
323+
scope.setTag("component-crashed", "true");
324+
scope.setTag("component-crashed-boundary", "ModuleErrorBoundary");
325+
scope.setLevel("fatal");
326+
Sentry.captureException(props.error);
327+
});
328+
}, [props.error]);
329+
330+
return (
331+
<div className="flex h-[190px] w-full items-center justify-center border border-border">
332+
Failed to render {props.moduleName} module
333+
</div>
334+
);
335+
}

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/module-instance.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import { lazy } from "react";
44
import type { ThirdwebContract } from "thirdweb";
55
import type { Account } from "thirdweb/wallets";
6-
import BatchMetadataModule from "./BatchMetadata";
7-
import ClaimableModule from "./Claimable";
8-
import OpenEditionMetadataModule from "./OpenEditionMetadata";
96
import { ModuleCardUI, type ModuleCardUIProps } from "./module-card";
107

118
const MintableModule = lazy(() => import("./Mintable"));
129
const TransferableModule = lazy(() => import("./Transferable"));
1310
const RoyaltyModule = lazy(() => import("./Royalty"));
11+
const BatchMetadataModule = lazy(() => import("./BatchMetadata"));
12+
const ClaimableModule = lazy(() => import("./Claimable"));
13+
const OpenEditionMetadataModule = lazy(() => import("./OpenEditionMetadata"));
1414

1515
export type ModuleInstanceProps = Omit<
1616
ModuleCardUIProps,

0 commit comments

Comments
 (0)