routeNotFound.tsx 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import {useEffect} from 'react';
  2. import {RouteComponentProps} from 'react-router';
  3. import * as Sentry from '@sentry/react';
  4. import NotFound from 'sentry/components/errors/notFound';
  5. import Footer from 'sentry/components/footer';
  6. import * as Layout from 'sentry/components/layouts/thirds';
  7. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  8. import Sidebar from 'sentry/components/sidebar';
  9. import {t} from 'sentry/locale';
  10. type Props = RouteComponentProps<{}, {}>;
  11. function RouteNotFound({router, location}: Props) {
  12. const {pathname, search, hash} = location;
  13. const isMissingSlash = pathname[pathname.length - 1] !== '/';
  14. useEffect(() => {
  15. // Attempt to fix trailing slashes first
  16. if (isMissingSlash) {
  17. router.replace(`${pathname}/${search}${hash}`);
  18. return;
  19. }
  20. Sentry.withScope(scope => {
  21. scope.setFingerprint(['RouteNotFound']);
  22. Sentry.captureException(new Error('Route not found'));
  23. });
  24. }, [pathname, search, hash, isMissingSlash, router]);
  25. if (isMissingSlash) {
  26. return null;
  27. }
  28. return (
  29. <SentryDocumentTitle title={t('Page Not Found')}>
  30. <div className="app">
  31. <Sidebar location={location} />
  32. <Layout.Page withPadding>
  33. <NotFound />
  34. </Layout.Page>
  35. <Footer />
  36. </div>
  37. </SentryDocumentTitle>
  38. );
  39. }
  40. export default RouteNotFound;