routeNotFound.tsx 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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 SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  7. import Sidebar from 'sentry/components/sidebar';
  8. import {t} from 'sentry/locale';
  9. type Props = RouteComponentProps<{}, {}>;
  10. function RouteNotFound({router, location}: Props) {
  11. const {pathname, search, hash} = location;
  12. const isMissingSlash = pathname[pathname.length - 1] !== '/';
  13. useEffect(() => {
  14. // Attempt to fix trailing slashes first
  15. if (isMissingSlash) {
  16. router.replace(`${pathname}/${search}${hash}`);
  17. return;
  18. }
  19. Sentry.withScope(scope => {
  20. scope.setFingerprint(['RouteNotFound']);
  21. Sentry.captureException(new Error('Route not found'));
  22. });
  23. }, [pathname, search, hash, isMissingSlash, router]);
  24. if (isMissingSlash) {
  25. return null;
  26. }
  27. return (
  28. <SentryDocumentTitle title={t('Page Not Found')}>
  29. <div className="app">
  30. <Sidebar location={location} />
  31. <div className="container">
  32. <div className="content">
  33. <section className="body">
  34. <NotFound />
  35. </section>
  36. </div>
  37. </div>
  38. <Footer />
  39. </div>
  40. </SentryDocumentTitle>
  41. );
  42. }
  43. export default RouteNotFound;