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: ensure signing out cannot cause any runtime render errors #13137

Merged
merged 21 commits into from
May 3, 2024

Conversation

Parkreiner
Copy link
Contributor

@Parkreiner Parkreiner commented May 3, 2024

Closes #13130

Changes made

  • Created an entire fully-type-safe state management system for exposing all the metadata in a render-safe way for the UI
    • We've had a couple of bugs specifically around bringing this metadata in already. If we're going to keep bringing in more and more data, we need a way to centralize it, and make sure it can pipe into React/React Query well
    • Critically, this system allows you to delete metadata (the bug fix for this issue involves deleting the user metadata in the HTML, and making sure the stale data isn't persisted in any variables)
  • Updates how we're placing error boundaries to greatly decrease our odds of more uncaught runtime errors slipping through the UI
    • I want to update our error boundary component a bit, but that'll be done in a later PR
  • Updates how we're integrating the React Query dev tools to make sure nothing breaks there either

Notes

  • I would eventually like to make a useMetadataQuery hook to improve the ergonomics of wiring up our metadata to React Query, but this is a decent first step towards that
  • Going to make a separate PR for making an E2E test to make sure we catch any possible logout bugs

@Parkreiner Parkreiner self-assigned this May 3, 2024
Comment on lines +77 to +81
<ErrorBoundary>
<AppProviders>
<RouterProvider router={router} />
</ErrorBoundary>
</AppProviders>
</AppProviders>
</ErrorBoundary>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Important – before, if any of the sub-components in AppProviders threw an error, we had nothing to catch it. Moved ErrorBoundary to be the top-most component

Comment on lines -109 to -113
const obj = JSON.parse(rawContent as string);
if ("regions" in obj) {
return obj.regions as Region[];
}
return obj as Region[];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Emyrk I wasn't completely sure why we had a check for whether the data getting parsed was either an array or an object with the array inside it, but just to be on the safe side, I ripped this out and centralized it in the metadata manager file

Copy link
Member

@Emyrk Emyrk May 3, 2024

Choose a reason for hiding this comment

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

Great question. The type safety we have on these fields is terrible, and should be resolved imo to make things like this more clear. We just inject strings that are json. Very weak imo.

I'll dig a bit and find out

Comment on lines +108 to +116
metadata: metadata.regions,
queryKey: ["get-proxies"],
queryFn: async (): Promise<readonly Region[]> => {
const endpoint = permissions.editWorkspaceProxies
? getWorkspaceProxies
: getWorkspaceProxyRegions;
const resp = await endpoint();
return resp.regions;
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just inlined a bunch of the values, since they're only used here

Comment on lines +193 to +208
/**
* 2024-05-02 - If we persist any form of user data after the user logs
* out, that will continue to seed the React Query cache, creating
* "impossible" states where we'll have data we're not supposed to have.
*
* This has caused issues where logging out will instantly throw a
* completely uncaught runtime rendering error. Worse yet, the error only
* exists when serving the site from the Go backend (the JS environment
* has zero issues because it doesn't have access to the metadata). These
* errors can only be caught with E2E tests.
*
* Deleting the user data will mean that all future requests have to take
* a full roundtrip, but this still felt like the best way to ensure that
* manually logging out doesn't blow the entire app up.
*/
defaultMetadataManager.clearMetadataByKey("user");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the main part of the fix

Comment on lines +47 to +51
const isHomePage = location.pathname === "/";
const navigateTo = isHomePage
? "/login"
: embedRedirect(`${location.pathname}${location.search}`);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved the variables here because they're only relevant for this block

const experimentsKey = ["experiments"] as const;

export const experiments = (): UseQueryOptions<Experiments> => {
export const experiments = (metadata: MetadataState<Experiments>) => {
Copy link
Contributor Author

@Parkreiner Parkreiner May 3, 2024

Choose a reason for hiding this comment

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

I do want to go back and add explicit return types, but I was on a tight deadline, and didn't have time to figure it out

These functions are still type-safe and will let you know if you wire things wrong. They're just not "add explicit type parameter"-safe, because of TypeScript type parameter shenanigans

@Parkreiner Parkreiner marked this pull request as ready for review May 3, 2024 13:52
@Parkreiner Parkreiner changed the title fix: stop "sign out" button from breaking entire UI fix: stop "sign out" button from breaking UI with uncaught runtime error May 3, 2024
@Parkreiner Parkreiner changed the title fix: stop "sign out" button from breaking UI with uncaught runtime error fix: ensure signing out cannot cause any runtime render errors May 3, 2024
@BrunoQuaresma
Copy link
Collaborator

I found this fix quite complex but comprehensible 👍 good job. I also tested it locally.

@Parkreiner Parkreiner merged commit 7873c96 into main May 3, 2024
32 checks passed
@Parkreiner Parkreiner deleted the mes/login-fix branch May 3, 2024 14:40
@github-actions github-actions bot locked and limited conversation to collaborators May 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
3 participants