diff --git a/frontend/src/metabase-types/store/app.ts b/frontend/src/metabase-types/store/app.ts index 4d1d881346eabcfb53fce3e3822bb6b7bc7b9042..02f379512bb7397f7fb60afc966012afcaeb0b3c 100644 --- a/frontend/src/metabase-types/store/app.ts +++ b/frontend/src/metabase-types/store/app.ts @@ -2,7 +2,7 @@ export interface AppErrorDescriptor { status: number; data?: { error_code: string; - message: string; + message?: string; }; context?: string; } diff --git a/frontend/src/metabase/App.tsx b/frontend/src/metabase/App.tsx index 65dac18a6accd88773f7d1754cac3e0458e0e55f..2794d9b1f68e2aa0733194fdc2407bbb1ec7cc24 100644 --- a/frontend/src/metabase/App.tsx +++ b/frontend/src/metabase/App.tsx @@ -30,7 +30,7 @@ import { AppErrorDescriptor, State } from "metabase-types/store"; import { AppContentContainer, AppContent } from "./App.styled"; const getErrorComponent = ({ status, data, context }: AppErrorDescriptor) => { - if (status === 403) { + if (status === 403 || data?.error_code === "unauthorized") { return <Unauthorized />; } if (status === 404 || data?.error_code === "not-found") { @@ -119,19 +119,15 @@ function App({ return ( <ErrorBoundary onError={setErrorInfo}> <ScrollToTop> - {errorPage ? ( - getErrorComponent(errorPage) - ) : ( - <> - {hasAppBar && <AppBar />} - <AppContentContainer hasAppBar={hasAppBar} isAdminApp={isAdminApp}> - {hasNavbar && <Navbar />} - <AppContent>{children}</AppContent> - <UndoListing /> - <StatusListing /> - </AppContentContainer> - </> - )} + {hasAppBar && <AppBar />} + <AppContentContainer hasAppBar={hasAppBar} isAdminApp={isAdminApp}> + {hasNavbar && <Navbar />} + <AppContent> + {errorPage ? getErrorComponent(errorPage) : children} + </AppContent> + <UndoListing /> + <StatusListing /> + </AppContentContainer> <AppErrorCard errorInfo={errorInfo} /> </ScrollToTop> </ErrorBoundary> diff --git a/frontend/src/metabase/containers/NotFoundFallbackPage.tsx b/frontend/src/metabase/containers/NotFoundFallbackPage.tsx new file mode 100644 index 0000000000000000000000000000000000000000..1766c7b1c5a7bdabdd5fc279a80cbcfa090c5d52 --- /dev/null +++ b/frontend/src/metabase/containers/NotFoundFallbackPage.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import { connect } from "react-redux"; +import { replace } from "react-router-redux"; +import { LocationDescriptor } from "history"; + +import { refreshCurrentUser } from "metabase/redux/user"; +import { useOnMount } from "metabase/hooks/use-on-mount"; + +import { NotFound } from "./ErrorPages"; + +type DispatchProps = { + refreshCurrentUser: () => any; + onChangeLocation: (location: LocationDescriptor) => void; +}; + +type Props = DispatchProps; + +const mapDispatchToProps = { + refreshCurrentUser, + onChangeLocation: replace, +}; + +const NotFoundFallbackPage = ({ + refreshCurrentUser, + onChangeLocation, +}: Props) => { + useOnMount(() => { + async function refresh() { + const result = await refreshCurrentUser(); + const isSignedIn = !result.error; + if (!isSignedIn) { + onChangeLocation("/auth/login"); + } + } + refresh(); + }); + + return <NotFound />; +}; + +export default connect(null, mapDispatchToProps)(NotFoundFallbackPage); diff --git a/frontend/src/metabase/routes.jsx b/frontend/src/metabase/routes.jsx index 4a4b2aaf3a7d3bd38b201c4b296fba2e89aa16b8..c3cb251a0ec38da582b7e29356be0cfa3b1d6ba4 100644 --- a/frontend/src/metabase/routes.jsx +++ b/frontend/src/metabase/routes.jsx @@ -46,7 +46,8 @@ import NewQueryOptions from "metabase/new_query/containers/NewQueryOptions"; import CreateDashboardModal from "metabase/components/CreateDashboardModal"; -import { NotFound, Unauthorized } from "metabase/containers/ErrorPages"; +import { Unauthorized } from "metabase/containers/ErrorPages"; +import NotFoundFallbackPage from "metabase/containers/NotFoundFallbackPage"; // Reference Metrics import MetricListContainer from "metabase/reference/metrics/MetricListContainer"; @@ -391,6 +392,6 @@ export const getRoutes = store => ( {/* MISC */} <Route path="/unauthorized" component={Unauthorized} /> - <Route path="/*" component={NotFound} /> + <Route path="/*" component={NotFoundFallbackPage} /> </Route> );