Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

fix: handle backend errors in pool page #1031

Merged
merged 13 commits into from
Sep 13, 2024
40 changes: 25 additions & 15 deletions app/(app)/pools/[chain]/[variant]/[id]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { PoolDetailSkeleton } from '@/lib/modules/pool/PoolDetail/PoolDetailSkel
import { getApolloServerClient } from '@/lib/shared/services/api/apollo-server.client'
import { GetPoolDocument } from '@/lib/shared/services/api/generated/graphql'
import { Metadata } from 'next'
import { Box } from '@chakra-ui/react'
import { PoolProvider } from '@/lib/modules/pool/PoolProvider'
import { getProjectConfig } from '@/lib/config/getProjectConfig'
import { arrayToSentence } from '@/lib/shared/utils/strings'
import { ensureError } from '@/lib/shared/utils/errors'

type Props = PropsWithChildren<{
params: Omit<FetchPoolProps, 'chain'> & { chain: ChainSlug }
Expand All @@ -21,24 +21,28 @@ async function getPoolQuery(chain: ChainSlug, id: string) {
const _chain = slugToChainMap[chain]
const variables = { id: id.toLowerCase(), chain: _chain }

return await getApolloServerClient().query({
query: GetPoolDocument,
variables,
context: {
fetchOptions: {
next: { revalidate: 30 },
try {
const result = await getApolloServerClient().query({
query: GetPoolDocument,
variables,
context: {
fetchOptions: {
next: { revalidate: 30 },
},
},
},
})
})
return { data: result.data, error: null }
} catch (error: unknown) {
return { data: null, error: ensureError(error) }
}
}

export async function generateMetadata({
params: { id, chain, variant },
}: Props): Promise<Metadata> {
const {
data: { pool },
} = await getPoolQuery(chain, id)
const { data } = await getPoolQuery(chain, id)

const pool = data?.pool
if (!pool) return {}

const poolTokenString = arrayToSentence(pool.displayTokens.map(token => token.symbol))
Expand All @@ -54,12 +58,18 @@ export async function generateMetadata({
export default async function PoolLayout({ params: { id, chain, variant }, children }: Props) {
const _chain = slugToChainMap[chain]

const { data } = await getPoolQuery(chain, id)
const { data, error } = await getPoolQuery(chain, id)

if (!data.pool) {
return <Box>Pool with id not found ({id})</Box>
if (error) {
if (error?.message === 'Pool with id does not exist') {
agualis marked this conversation as resolved.
Show resolved Hide resolved
throw new Error(`Pool not found on ${chain}, ID: ${id}`)
}

throw new Error('Failed to fetch pool')
}

if (!data) return null

return (
<Suspense fallback={<PoolDetailSkeleton />}>
<PoolProvider id={id} chain={_chain} variant={variant} data={data}>
Expand Down
13 changes: 11 additions & 2 deletions lib/shared/components/alerts/BalAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export type BalAlertProps = {
isSoftWarning?: boolean
isNavAlert?: boolean
onClose?: MouseEventHandler
ssr?: boolean
}

export function BalAlert({
Expand All @@ -18,13 +19,21 @@ export function BalAlert({
learnMoreLink,
isSoftWarning = false,
isNavAlert = false,
ssr = false, // Use true whe rendering alerts on the server side
agualis marked this conversation as resolved.
Show resolved Hide resolved
onClose,
}: BalAlertProps) {
return (
<Alert status={status} rounded={isNavAlert ? 'none' : 'default'}>
<AlertIcon as={getAlertIcon(status)} />
{ssr ? <AlertIcon /> : <AlertIcon as={getAlertIcon(status)} />}

<AlertTitle gap={1} display="flex" w="full" color="black">
<AlertTitle
gap={1}
display="flex"
w="full"
color="black"
wordBreak="break-word"
flexDirection="column"
>
{content}
</AlertTitle>
{learnMoreLink && <BalAlertButtonLink href={learnMoreLink}>More</BalAlertButtonLink>}
Expand Down
2 changes: 1 addition & 1 deletion lib/shared/components/containers/DefaultPageContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function DefaultPageContainer({
...rest
}: PropsWithChildren & ContainerProps & Props) {
return (
<Box pt={noVerticalPadding ? '0px' : '72px'}>
<Box pt={noVerticalPadding ? '0px' : '72px'} minH="50vh">
<Container
maxW="maxContent"
py={noVerticalPadding ? 0 : ['xl', '2xl']}
Expand Down
11 changes: 4 additions & 7 deletions lib/shared/components/errors/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ import { FallbackProps } from 'react-error-boundary'
import { Button, Box, Text, Heading, VStack } from '@chakra-ui/react'
import { ensureError } from '../../utils/errors'
import { DefaultPageContainer } from '../containers/DefaultPageContainer'
import { captureSentryError } from '../../utils/query-errors'

export function BoundaryError({ error, resetErrorBoundary }: FallbackProps) {
captureSentryError(error, { errorMessage: error.message })

export function BoundaryError({
error,
resetErrorBoundary,
}: {
error: Error & { digest?: string }
resetErrorBoundary: () => void
}) {
const _error = ensureError(error)

return (
Expand Down
2 changes: 1 addition & 1 deletion lib/shared/utils/query-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { SwapHandler } from '@/lib/modules/swap/handlers/Swap.handler'
export type SentryMetadata = {
errorMessage: string
errorName?: string
context: Partial<ScopeContext>
context?: Partial<ScopeContext>
}

export function sentryMetaForAddLiquidityHandler(errorMessage: string, params: AddLiquidityParams) {
Expand Down
2 changes: 2 additions & 0 deletions sentry.server.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import * as Sentry from '@sentry/nextjs'
import { sentryDSN } from './sentry.config'
import { isProd } from './lib/config/app.config'

Sentry.init({
enabled: isProd,
dsn: sentryDSN,
// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 0,
Expand Down
Loading