diff --git a/apps/compliance-portal/src/components/ComplianceFrameworks/ComplianceFrameworkListItem.tsx b/apps/compliance-portal/src/components/ComplianceFrameworks/ComplianceFrameworkListItem.tsx index 4e291c858..fe8cd47d1 100644 --- a/apps/compliance-portal/src/components/ComplianceFrameworks/ComplianceFrameworkListItem.tsx +++ b/apps/compliance-portal/src/components/ComplianceFrameworks/ComplianceFrameworkListItem.tsx @@ -27,7 +27,7 @@ import { MediaTile } from "#/components/MediaTile/MediaTile"; import type { ComplianceFrameworkListItem_complianceFramework$key } from "./__generated__/ComplianceFrameworkListItem_complianceFramework.graphql"; const complianceFrameworkListItemFragment = graphql` - fragment ComplianceFrameworkListItem_complianceFramework on ComplianceFramework { + fragment ComplianceFrameworkListItem_complianceFramework on ComplianceFramework @throwOnFieldError { framework { name themedLogoUrl diff --git a/apps/compliance-portal/src/components/TrustedBy/TrustCenterReferenceListItem.tsx b/apps/compliance-portal/src/components/TrustedBy/TrustCenterReferenceListItem.tsx index 0b25d17fe..8d768c9a0 100644 --- a/apps/compliance-portal/src/components/TrustedBy/TrustCenterReferenceListItem.tsx +++ b/apps/compliance-portal/src/components/TrustedBy/TrustCenterReferenceListItem.tsx @@ -27,7 +27,7 @@ import { externalHref } from "#/lib/url/hostname"; import type { TrustCenterReferenceListItem_reference$key } from "./__generated__/TrustCenterReferenceListItem_reference.graphql"; const trustCenterReferenceListItemFragment = graphql` - fragment TrustCenterReferenceListItem_reference on TrustCenterReference { + fragment TrustCenterReferenceListItem_reference on TrustCenterReference @throwOnFieldError { name websiteUrl logo { diff --git a/apps/compliance-portal/src/components/TrustedBy/TrustedBySection.tsx b/apps/compliance-portal/src/components/TrustedBy/TrustedBySection.tsx index 42b17c424..323520dd5 100644 --- a/apps/compliance-portal/src/components/TrustedBy/TrustedBySection.tsx +++ b/apps/compliance-portal/src/components/TrustedBy/TrustedBySection.tsx @@ -18,6 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +import { ErrorBoundary } from "@probo/ui/src/v2/ErrorBoundary/ErrorBoundary"; +import { InlineError } from "@probo/ui/src/v2/InlineError/InlineError"; import { useTranslation } from "react-i18next"; import { graphql, useFragment } from "react-relay"; @@ -26,8 +28,10 @@ import { HomeSection } from "#/components/HomeSection/HomeSection"; import type { TrustedBySection_trustCenter$key } from "./__generated__/TrustedBySection_trustCenter.graphql"; import { TrustCenterReferenceListItem } from "./TrustCenterReferenceListItem"; +// @throwOnFieldError surfaces a field error at the read below so the section +// ErrorBoundary contains it. See contrib/claude/error-handling.md. const trustedBySectionFragment = graphql` - fragment TrustedBySection_trustCenter on TrustCenter { + fragment TrustedBySection_trustCenter on TrustCenter @throwOnFieldError { references(first: 12) { edges { node { @@ -43,9 +47,32 @@ interface TrustedBySectionProps { trustCenterKey: TrustedBySection_trustCenter$key; } -// "Trusted by" section: a grid of customer / reference logos. +// "Trusted by" section: a grid of customer / reference logos. A load failure +// degrades to an inline error instead of taking down the page. export function TrustedBySection({ trustCenterKey }: TrustedBySectionProps) { const { t } = useTranslation(); + + return ( + + window.location.reload()} + /> + + )} + > + + + ); +} + +function TrustedBySectionContent({ trustCenterKey }: TrustedBySectionProps) { + const { t } = useTranslation(); const data = useFragment(trustedBySectionFragment, trustCenterKey); const references = data.references.edges.map(edge => edge.node);