From 1d441c17f3195e2fa79d344f58de9012a06f4f05 Mon Sep 17 00:00:00 2001 From: Kristof Csillag Date: Mon, 19 Jun 2023 12:27:23 +0200 Subject: [PATCH] Improve handling of routing errors on invalid layers - Don't throw more errors while already trying to display error - Use the most specific error message possible - Teach useScopeParam() to also return info about validity - Hide network selector and freshness info on invalid scopes --- .changelog/557.bugfix.md | 1 + src/app/components/PageLayout/Header.tsx | 2 +- src/app/components/PageLayout/index.tsx | 2 +- src/app/hooks/useScopeParam.ts | 40 +++++++++++++++--------- src/app/utils/route-utils.ts | 2 +- 5 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 .changelog/557.bugfix.md diff --git a/.changelog/557.bugfix.md b/.changelog/557.bugfix.md new file mode 100644 index 000000000..24359d99b --- /dev/null +++ b/.changelog/557.bugfix.md @@ -0,0 +1 @@ +Fix error display when using invalid layers diff --git a/src/app/components/PageLayout/Header.tsx b/src/app/components/PageLayout/Header.tsx index fb9825622..714044c07 100644 --- a/src/app/components/PageLayout/Header.tsx +++ b/src/app/components/PageLayout/Header.tsx @@ -66,7 +66,7 @@ export const Header: FC = () => { showText={!scrollTrigger && !isMobile} /> - {scope && ( + {scope?.valid && ( <> diff --git a/src/app/components/PageLayout/index.tsx b/src/app/components/PageLayout/index.tsx index a79024a43..cd5ca3a9f 100644 --- a/src/app/components/PageLayout/index.tsx +++ b/src/app/components/PageLayout/index.tsx @@ -46,7 +46,7 @@ export const PageLayout: FC> = ({ children, m - {scope && } + {scope?.valid && } { return network as Network | undefined } +type ScopeInfo = SearchScope & { + valid: boolean +} + /** * Use this in situations where we might or might not have a scope */ -export const useScopeParam = (): SearchScope | undefined => { +export const useScopeParam = (): ScopeInfo | undefined => { const { network, layer } = useParams() + const error = useRouteError() if (network === undefined && layer === undefined) return undefined - if (network === undefined || layer === undefined) { - throw new Error( - 'You must either specify both network and layer or none of them. You can not have one but not the other.', - ) - } - - const scope: SearchScope = { + const scope: ScopeInfo = { network: network as Network, layer: layer as Layer, + valid: true, } - if (!scope || !RouteUtils.getEnabledNetworks().includes(scope.network)) - throw new AppError(AppErrors.UnsupportedNetwork) + if (network === undefined || layer === undefined) { + scope.valid = false + if (!error) + throw new Error( + 'You must either specify both network and layer or none of them. You can not have one but not the other.', + ) + } - if (!RouteUtils.getEnabledLayersForNetwork(scope.network).includes(scope.layer)) - throw new AppError(AppErrors.UnsupportedLayer) + if (!RouteUtils.getEnabledNetworks().includes(scope.network)) { + scope.valid = false + if (!error) throw new AppError(AppErrors.UnsupportedNetwork) + } + + if (!RouteUtils.getEnabledLayersForNetwork(scope.network).includes(scope.layer)) { + scope.valid = false + if (!error) throw new AppError(AppErrors.UnsupportedLayer) + } return scope } @@ -41,7 +53,7 @@ export const useScopeParam = (): SearchScope | undefined => { /** * Use this in situations where we require to have a scope */ -export const useRequiredScopeParam = (): SearchScope => { +export const useRequiredScopeParam = (): ScopeInfo => { const scope = useScopeParam() if (!scope) throw new AppError(AppErrors.UnsupportedNetwork) diff --git a/src/app/utils/route-utils.ts b/src/app/utils/route-utils.ts index 1d18d34fe..c3f3b4fb5 100644 --- a/src/app/utils/route-utils.ts +++ b/src/app/utils/route-utils.ts @@ -143,7 +143,7 @@ export const scopeLoader = async (args: LoaderFunctionArgs) => { !layer || // missing param !RouteUtils.getEnabledLayersForNetwork(network as Network).includes(layer as Layer) // unsupported on network ) { - throw new AppError(AppErrors.InvalidUrl) + throw new AppError(AppErrors.UnsupportedLayer) } return true