Skip to content

Commit

Permalink
fix(routes): track last route in routeNotFound (#77835)
Browse files Browse the repository at this point in the history
### The problem
In Sentry today, tons of “route not found” events are grouped together
into one issue, even if the suspect routes/transactions are not related.
This poses a problem because the relevant teams are not alerted to these
issues, which means
1) we’re not able to triage & fix these issues as quickly, and 
2) we do not have proper scope of the problem areas. 

See an issue example
[here](https://sentry.sentry.io/issues/496412334/events/c7dce88ad52944a095d672d0d114d7da/?project=11276&referrer=replay-errors),
and notice that not all the
[events](https://sentry.sentry.io/issues/496412334/events/c720b6d1807849b9ae0859f9b165a344/events/?project=11276&referrer=next-event)
have the same transaction.

### The goal
Improve our grouping for “route not found” issues so that the events are
split up into better issues — specifically, based on where the last
known route was. That way, we can have more relevant issues grouped by
(hopefully) the suspect problem route & triage more effectively.

### Next steps
Next step would be setting the fingerprinting rules in the `javascript`
project to include the new tag-based grouping rule. This is in project
settings:
<img width="1061" alt="SCR-20240919-tsyc"
src="https://github.com/user-attachments/assets/d2f22c3d-e892-4303-868e-520d15c36ac9">


[notion
doc](https://www.notion.so/sentry/Improve-Route-not-found-issue-grouping-1068b10e4b5d80129e5dc9b84b1b5eb5?showMoveTo=true&saveParent=true)
  • Loading branch information
michellewzhang authored Sep 23, 2024
1 parent 347ede1 commit 07396b7
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 17 deletions.
35 changes: 19 additions & 16 deletions static/app/views/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {useLocation} from 'sentry/utils/useLocation';
import {useUser} from 'sentry/utils/useUser';
import type {InstallWizardProps} from 'sentry/views/admin/installWizard';
import {AsyncSDKIntegrationContextProvider} from 'sentry/views/app/asyncSDKIntegrationProvider';
import LastKnownRouteContextProvider from 'sentry/views/lastKnownRouteContextProvider';
import {OrganizationContextProvider} from 'sentry/views/organizationContext';
import RouteAnalyticsContextProvider from 'sentry/views/routeAnalyticsContextProvider';

Expand Down Expand Up @@ -241,22 +242,24 @@ function App({children, params}: Props) {

return (
<Profiler id="App" onRender={onRenderCallback}>
<RouteAnalyticsContextProvider>
<OrganizationContextProvider>
<AsyncSDKIntegrationContextProvider>
<GlobalDrawer>
<GlobalFeedbackForm>
<MainContainer tabIndex={-1} ref={mainContainerRef}>
<GlobalModal onClose={handleModalClose} />
<SystemAlerts className="messages-container" />
<Indicators className="indicators-container" />
<ErrorBoundary>{renderBody()}</ErrorBoundary>
</MainContainer>
</GlobalFeedbackForm>
</GlobalDrawer>
</AsyncSDKIntegrationContextProvider>
</OrganizationContextProvider>
</RouteAnalyticsContextProvider>
<LastKnownRouteContextProvider>
<RouteAnalyticsContextProvider>
<OrganizationContextProvider>
<AsyncSDKIntegrationContextProvider>
<GlobalDrawer>
<GlobalFeedbackForm>
<MainContainer tabIndex={-1} ref={mainContainerRef}>
<GlobalModal onClose={handleModalClose} />
<SystemAlerts className="messages-container" />
<Indicators className="indicators-container" />
<ErrorBoundary>{renderBody()}</ErrorBoundary>
</MainContainer>
</GlobalFeedbackForm>
</GlobalDrawer>
</AsyncSDKIntegrationContextProvider>
</OrganizationContextProvider>
</RouteAnalyticsContextProvider>
</LastKnownRouteContextProvider>
</Profiler>
);
}
Expand Down
31 changes: 31 additions & 0 deletions static/app/views/lastKnownRouteContextProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {createContext, useContext} from 'react';

import getRouteStringFromRoutes from 'sentry/utils/getRouteStringFromRoutes';
import usePrevious from 'sentry/utils/usePrevious';
import {useRoutes} from 'sentry/utils/useRoutes';

interface Props {
children: React.ReactNode;
}

export const LastKnownRouteContext = createContext<string>('<unknown>');

export function useLastKnownRoute() {
return useContext(LastKnownRouteContext);
}

/**
* This provider tracks the last known route that the user has navigated to.
* This is used to better group issues when we hit "route not found" errors.
*/
export default function LastKnownRouteContextProvider({children}: Props) {
const route = useRoutes();
const prevRoute = usePrevious(route);
const lastKnownRoute = getRouteStringFromRoutes(prevRoute);

return (
<LastKnownRouteContext.Provider value={lastKnownRoute}>
{children}
</LastKnownRouteContext.Provider>
);
}
5 changes: 4 additions & 1 deletion static/app/views/routeNotFound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
import Sidebar from 'sentry/components/sidebar';
import {t} from 'sentry/locale';
import type {RouteComponentProps} from 'sentry/types/legacyReactRouter';
import {useLastKnownRoute} from 'sentry/views/lastKnownRouteContextProvider';

type Props = RouteComponentProps<{}, {}>;

function RouteNotFound({router, location}: Props) {
const {pathname, search, hash} = location;
const lastKnownRoute = useLastKnownRoute();

const isMissingSlash = pathname[pathname.length - 1] !== '/';

Expand All @@ -27,13 +29,14 @@ function RouteNotFound({router, location}: Props) {
scope.setFingerprint(['RouteNotFound']);
scope.setTag('isMissingSlash', isMissingSlash);
scope.setTag('pathname', pathname);
scope.setTag('lastKnownRoute', lastKnownRoute);
scope.setTag(
'reactRouterVersion',
window.__SENTRY_USING_REACT_ROUTER_SIX ? '6' : '3'
);
Sentry.captureException(new Error('Route not found'));
});
}, [pathname, search, hash, isMissingSlash, router]);
}, [pathname, search, hash, isMissingSlash, router, lastKnownRoute]);

if (isMissingSlash) {
return null;
Expand Down

0 comments on commit 07396b7

Please sign in to comment.