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

feat: add error boundaries and suspense usage with TRPC #93

Merged
merged 16 commits into from
May 22, 2023

Conversation

austinwoon
Copy link
Contributor

@austinwoon austinwoon commented May 17, 2023

Problem

Problem 1

Our current method of fetching data for pages with query params utilize getServerSideProps. We noticed a trend of slow initial load times for these pages as long as ~7s. This is likely (but not confirmed) attributed to Chakra's huge bundle size which slows down the time needed to build the server rendered page.

Solutions considered to root problem

We had two options

  • Attempt to fix getServerSideProps's bundle issues with Chakra - possibly looking into how we can treeshake chakra for server rendered pages to reduce build times
  • Introduce CSR patterns in our application

We went with option 2 as that was already in the existing roadmap.

Problem 2

Existing CSR patterns with page based routing was cumbersome as we could not use React 18's Suspense and the default ErrorBoundary from react-error-boundary.

This led to 2 dx issues:

  • In every component where we use query, we had to track isLoading and isError states and render the fallback components accordingly
  • There was a lack of a top level ErrorBoundary which would catch any errors thrown within child components which useSuspenseQuery

Solution

  • The inability to use React's Suspense component was due to the fact that any child component which calls the useRouter hook erroring out during server side rendering as the router had not mounted. T
    • To mitigate this, we created our own Suspense wrapper that keeps track of a isMounted state.
      • If the router is ready, we will render React's Suspense with the children
      • If router is not ready, fallbackComponent will render.
  • Created our own ErrorBoundary wrapper which catches error boundary states to render the correct fallback components

Improvements:

  • Refactored all queries to utilise useSuspenseQuery
  • Updated logic to handle redirects between sign-in and dashboard
  • Updated centralised logic for unauthorised errors redirecting to sign-in. This logic for this is now located in the ErrorBoundary component whenever a TRPCError has a code of UNAUTHORIZED

Tests

  • Navigating to dashboard without logging in succesfully redirects me to sign-in
  • Navigating to sign-in whilst authed redirects me to either callbackUrl or dashboard
  • ErrorBoundary fallback component renders on different TRPCError codes
  • Suspense fallback renders when data is suspending

@vercel
Copy link

vercel bot commented May 17, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
starter-kit ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 22, 2023 5:56am

@austinwoon austinwoon changed the title Feat/add error boundaries and suspense feat: add error boundaries and suspense May 17, 2023
@austinwoon austinwoon changed the title feat: add error boundaries and suspense feat: add error boundaries and suspense usage with TRPC May 17, 2023
Comment on lines 43 to 57
// The choice to not redirect via next's router was intentional to handle ErrorBoundary for the app root
// Using next's router.push('/sign-in') will not render the SignIn component as it won't be mounted in the app root as the ErrorBoundary fallback component will be rendered instead
// Using vanilla location redirecting will prompt a full page reload of /sign-in page, which will never trigger the root ErrorBoundary, thus rendering the full component correctly
if (res.data === 'UNAUTHORIZED') {
window.location.href = 'sign-in'
return
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@karrui @dvrylc check out this statement for the root level ErrorBoundary and lmk what you think. We can walk through tomorrow if docs arent clear.

src/pages/_app.tsx Outdated Show resolved Hide resolved
src/components/Suspense/Suspense.tsx Show resolved Hide resolved
src/components/ErrorBoundary/ErrorBoundary.tsx Outdated Show resolved Hide resolved
src/features/profile/api/useUser.ts Show resolved Hide resolved
src/pages/sign-in.tsx Outdated Show resolved Hide resolved
src/utils/trpc.ts Show resolved Hide resolved
@karrui
Copy link
Collaborator

karrui commented May 22, 2023

e2e tests failing, but fixed in #94. Can rebase/merge develop in first?

@austinwoon austinwoon force-pushed the feat/add-error-boundaries-and-suspense branch from af6d876 to 03d48e6 Compare May 22, 2023 05:55
@austinwoon
Copy link
Contributor Author

e2e tests failing, but fixed in #94. Can rebase/merge develop in first?

done

Copy link
Collaborator

@karrui karrui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@karrui karrui merged commit 3459c98 into develop May 22, 2023
4 checks passed
@karrui karrui deleted the feat/add-error-boundaries-and-suspense branch May 22, 2023 06:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants