Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle backend errors in pool page #1031

Merged
merged 13 commits into from
Sep 13, 2024
56 changes: 41 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,13 @@ 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 { DefaultPageContainer } from '@/lib/shared/components/containers/DefaultPageContainer'
import { BalAlert } from '@/lib/shared/components/alerts/BalAlert'
import { ensureError } from '@/lib/shared/utils/errors'
import { captureException } from '@sentry/nextjs'

type Props = PropsWithChildren<{
params: Omit<FetchPoolProps, 'chain'> & { chain: ChainSlug }
Expand All @@ -21,24 +24,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 +61,31 @@ 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
const error = `Pool with id not found in ${chain} (${id})`
agualis marked this conversation as resolved.
Show resolved Hide resolved
return (
<DefaultPageContainer>
<BalAlert status="error" content={error} ssr />
</DefaultPageContainer>
)
}
captureException(error, { level: 'fatal' })
return (
<DefaultPageContainer>
<BalAlert
status="warning"
content="Our API data provider appears to be having issues..."
agualis marked this conversation as resolved.
Show resolved Hide resolved
ssr
/>
</DefaultPageContainer>
)
}

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
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