From 7df3c60fa92d98df4c67a1a4299936b35eda94f3 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 30 Aug 2024 11:00:02 +0200 Subject: [PATCH] Implement envelope error boundary --- .../src/components/Election/Envelope.tsx | 49 ++++++++++++++++++- .../chakra-components/src/i18n/locales.ts | 1 + .../chakra-components/src/theme/envelope.ts | 2 + 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/chakra-components/src/components/Election/Envelope.tsx b/packages/chakra-components/src/components/Election/Envelope.tsx index 696676e3..f417479b 100644 --- a/packages/chakra-components/src/components/Election/Envelope.tsx +++ b/packages/chakra-components/src/components/Election/Envelope.tsx @@ -12,6 +12,7 @@ import { PublishedElection, } from '@vocdoni/sdk' import { format } from 'date-fns' +import { Component, ErrorInfo, PropsWithChildren, ReactNode, useEffect, useState } from 'react' export type VotePackageType = IVotePackage | IVoteEncryptedPackage @@ -48,8 +49,10 @@ export const Envelope = ({ {election.questions.map((q, i) => { return ( - {localize('envelopes.question_title', { title: q.title.default })} - + + {localize('envelopes.question_title', { title: q.title.default })} + + ) })} @@ -115,3 +118,45 @@ const SelectedOptions = ({ ) } + +type IErrorParams = { + question: IQuestion +} + +const EnvelopeError = ({ question }: IErrorParams) => { + const styles = useMultiStyleConfig('Envelope') + const { localize } = useElection() + + return ( + + {localize('envelopes.error_processing_envelope', { title: question?.title?.default || '' })} + + ) +} + +class EnvelopeErrorBoundary extends Component< + IErrorParams & PropsWithChildren, + { + hasError: boolean + } +> { + public state = { + hasError: false, + } + + public static getDerivedStateFromError(_: Error) { + return { hasError: true } + } + + public componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error('Uncaught error:', error, errorInfo) + } + + public render() { + if (this.state.hasError) { + return + } + + return this.props.children + } +} diff --git a/packages/chakra-components/src/i18n/locales.ts b/packages/chakra-components/src/i18n/locales.ts index addaa82b..59e4e37c 100644 --- a/packages/chakra-components/src/i18n/locales.ts +++ b/packages/chakra-components/src/i18n/locales.ts @@ -31,6 +31,7 @@ export const locales = { envelopes: { envelope_abstain_count: 'Abstained {{ count }} times', question_title: 'Option/s selected in "{{ title }}":', + error_processing_envelope: 'Cannot process envelope data for question "{{ title }}"', }, errors: { wrong_data_title: 'Wrong data', diff --git a/packages/chakra-components/src/theme/envelope.ts b/packages/chakra-components/src/theme/envelope.ts index f2381443..26bcba40 100644 --- a/packages/chakra-components/src/theme/envelope.ts +++ b/packages/chakra-components/src/theme/envelope.ts @@ -13,6 +13,8 @@ export const envelopeAnatomy = [ 'choiceTitle', // secret envelope (no results until the end text) 'secret', + // Error boundary message + 'error', ] const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(envelopeAnatomy)