From 09e974b7774ab0932f4c7df79ddd11006c302b14 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 23 Jan 2020 13:52:18 +0100 Subject: [PATCH] Handle DispatchError failures gracefully (#2182) * Handle DispatchError failures gracefully * Also allow queue display failures --- .../react-components/src/Status/Queue.tsx | 10 ++++-- .../react-params/src/Param/DispatchError.tsx | 34 +++++++++++++++---- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/packages/react-components/src/Status/Queue.tsx b/packages/react-components/src/Status/Queue.tsx index b8e03f99e6..bf54f76445 100644 --- a/packages/react-components/src/Status/Queue.tsx +++ b/packages/react-components/src/Status/Queue.tsx @@ -135,10 +135,14 @@ export default function Queue ({ children }: Props): React.ReactElement { let message = dispatchError.type; if (dispatchError.isModule) { - const mod = dispatchError.asModule; - const error = registry.findMetaError(new Uint8Array([mod.index.toNumber(), mod.error.toNumber()])); + try { + const mod = dispatchError.asModule; + const error = registry.findMetaError(new Uint8Array([mod.index.toNumber(), mod.error.toNumber()])); - message = `${error.section}.${error.name}`; + message = `${error.section}.${error.name}`; + } catch (error) { + // swallow + } } return { diff --git a/packages/react-params/src/Param/DispatchError.tsx b/packages/react-params/src/Param/DispatchError.tsx index 768a957dc8..7226ca9b1d 100644 --- a/packages/react-params/src/Param/DispatchError.tsx +++ b/packages/react-params/src/Param/DispatchError.tsx @@ -5,7 +5,7 @@ import { DispatchError } from '@polkadot/types/interfaces'; import { Props } from '../types'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { registry } from '@polkadot/react-api'; import { Input } from '@polkadot/react-components'; @@ -13,18 +13,38 @@ import { useTranslation } from '../translate'; import Static from './Static'; import Unknown from './Unknown'; +interface Details { + details?: string | null; + type?: string; +} + export default function ErrorDisplay (props: Props): React.ReactElement { const { t } = useTranslation(); + const [{ details, type }, setDetails] = useState
({}); - if (!props.isDisabled || !props.defaultValue?.value?.isModule) { + useEffect((): void => { + if (details !== null && props.defaultValue?.value?.isModule) { + try { + const mod = (props.defaultValue.value as DispatchError).asModule; + const error = registry.findMetaError(new Uint8Array([mod.index.toNumber(), mod.error.toNumber()])); + + setDetails({ + details: error.documentation.join(', '), + type: `${error.section}.${error.name}` + }); + } catch (error) { + // Errors may not actually be exposed, in this case, just return the default representation + console.error(error); + + setDetails({ details: null }); + } + } + }, [props.defaultValue]); + + if (!props.isDisabled || !details) { return ; } - const mod = (props.defaultValue.value as DispatchError).asModule; - const error = registry.findMetaError(new Uint8Array([mod.index.toNumber(), mod.error.toNumber()])); - const type = `${error.section}.${error.name}`; - const details = error.documentation.join(', '); - return (