This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 7e453ec50 refactor(config-ui): use new error catch to replace old
(#5712)
7e453ec50 is described below
commit 7e453ec5095260e0f955f4c6b3521573cb0a93ba
Author: 青湛 <[email protected]>
AuthorDate: Mon Jul 24 20:34:40 2023 +1200
refactor(config-ui): use new error catch to replace old (#5712)
---
config-ui/src/App.tsx | 20 +-------
config-ui/src/layouts/base/api.ts | 2 +-
config-ui/src/layouts/base/base.tsx | 31 +++++++-----
config-ui/src/layouts/error/styled.ts | 58 ---------------------
config-ui/src/layouts/index.ts | 1 -
config-ui/src/pages/index.ts | 2 -
.../routes/error/components/exception/index.tsx | 52 +++++++++++++++++++
.../{layouts => routes/error/components}/index.ts | 5 +-
.../error/components/needs-db-migrate}/api.ts | 0
.../error/components/needs-db-migrate}/index.tsx | 2 +-
.../error/components}/offline/api.ts | 0
.../error/components}/offline/index.tsx | 2 +-
.../error/index.tsx => routes/error/error.tsx} | 12 +++--
config-ui/src/{layouts => routes/error}/index.ts | 2 +-
config-ui/src/routes/error/index.tsx | 59 ----------------------
.../offline/api.ts => routes/error/types.ts} | 7 +--
config-ui/src/utils/request.ts | 13 -----
17 files changed, 93 insertions(+), 175 deletions(-)
diff --git a/config-ui/src/App.tsx b/config-ui/src/App.tsx
index 23a9d838a..0a993c44c 100644
--- a/config-ui/src/App.tsx
+++ b/config-ui/src/App.tsx
@@ -19,10 +19,8 @@
import { createBrowserRouter, Navigate, RouterProvider } from
'react-router-dom';
import { PageLoading } from '@/components';
-import { ErrorLayout, BaseLayout } from '@/layouts';
+import { loader as baseLayoutLoader, BaseLayout } from '@/layouts/base';
import {
- OfflinePage,
- DBMigratePage,
ConnectionHomePage,
ConnectionDetailPage,
ProjectHomePage,
@@ -34,24 +32,10 @@ import {
import { Error } from '@/routes/error';
const router = createBrowserRouter([
- {
- path: '',
- element: <ErrorLayout />,
- errorElement: <Error />,
- children: [
- {
- path: 'offline',
- element: <OfflinePage />,
- },
- {
- path: 'db-migrate',
- element: <DBMigratePage />,
- },
- ],
- },
{
path: '/',
element: <BaseLayout />,
+ loader: baseLayoutLoader,
errorElement: <Error />,
children: [
{
diff --git a/config-ui/src/layouts/base/api.ts
b/config-ui/src/layouts/base/api.ts
index c3be4bbac..63f0d4d98 100644
--- a/config-ui/src/layouts/base/api.ts
+++ b/config-ui/src/layouts/base/api.ts
@@ -24,5 +24,5 @@ export type UserInfo = {
logoutURI: string;
};
-export const getVersion = () => request('/version');
+export const getVersion = (signal?: AbortSignal): Promise<{ version: string }>
=> request('/version', { signal });
export const getUserInfo = (): Promise<UserInfo> => request('/userinfo');
diff --git a/config-ui/src/layouts/base/base.tsx
b/config-ui/src/layouts/base/base.tsx
index a677fa47d..f30e98fc5 100644
--- a/config-ui/src/layouts/base/base.tsx
+++ b/config-ui/src/layouts/base/base.tsx
@@ -17,13 +17,15 @@
*/
import { useState, useEffect, useRef } from 'react';
-import { Outlet, useNavigate, useLocation } from 'react-router-dom';
+import { useLoaderData, Outlet, useNavigate, useLocation, json } from
'react-router-dom';
import { CSSTransition } from 'react-transition-group';
import { Menu, MenuItem, Navbar, Alignment } from '@blueprintjs/core';
+import { AxiosError } from 'axios';
-import { PageLoading, Logo, ExternalLink, IconButton } from '@/components';
-import { useTips, useRefreshData } from '@/hooks';
+import { Logo, ExternalLink, IconButton } from '@/components';
+import { useTips } from '@/hooks';
import { TipsContextProvider, ConnectionContextProvider } from '@/store';
+import { ErrorEnum } from '@/routes/error';
import DashboardIcon from '@/images/icons/dashboard.svg';
import FileIcon from '@/images/icons/file.svg';
@@ -36,22 +38,27 @@ import * as API from './api';
import * as S from './styled';
import './tips-transition.css';
-export const BaseLayout = () => {
- const navigate = useNavigate();
- const { ready, data, error } = useRefreshData<{ version: string }>(() =>
API.getVersion(), []);
+export const loader = async ({ request }: { request: Request }) => {
+ try {
+ return await API.getVersion(request.signal);
+ } catch (err) {
+ const status = (err as AxiosError).response?.status;
- if (error) {
- navigate('/offline');
- }
+ if (status === 428) {
+ throw json({ error: ErrorEnum.NEEDS_DB_MIRGATE }, { status: 428 });
+ }
- if (!ready || !data) {
- return <PageLoading />;
+ throw json({ error: ErrorEnum.API_OFFLINE }, { status: 503 });
}
+};
+
+export const BaseLayout = () => {
+ const { version } = useLoaderData() as Awaited<ReturnType<typeof loader>>;
return (
<TipsContextProvider>
<ConnectionContextProvider>
- <Layout version={data.version}>
+ <Layout version={version}>
<Outlet />
</Layout>
</ConnectionContextProvider>
diff --git a/config-ui/src/layouts/error/styled.ts
b/config-ui/src/layouts/error/styled.ts
deleted file mode 100644
index 0b1dad056..000000000
--- a/config-ui/src/layouts/error/styled.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import styled from 'styled-components';
-import { Colors } from '@blueprintjs/core';
-
-export const Wrapper = styled.div`
- display: flex;
- flex-direction: column;
- align-items: center;
- padding-top: 100px;
- height: 100vh;
- background-color: #f9f9fa;
- box-sizing: border-box;
-`;
-
-export const Inner = styled.div`
- margin: 32px auto 0;
- width: 640px;
-
- h2 {
- display: flex;
- align-items: center;
- margin: 0;
-
- .bp4-icon {
- margin-right: 4px;
- }
- }
-
- p {
- margin: 16px 0;
-
- &.warning {
- color: ${Colors.ORANGE5};
- }
- }
-
- .bp4-button-group {
- display: flex;
- justify-content: center;
- }
-`;
diff --git a/config-ui/src/layouts/index.ts b/config-ui/src/layouts/index.ts
index 7e43f3d53..4a2f7c965 100644
--- a/config-ui/src/layouts/index.ts
+++ b/config-ui/src/layouts/index.ts
@@ -17,4 +17,3 @@
*/
export * from './base';
-export * from './error';
diff --git a/config-ui/src/pages/index.ts b/config-ui/src/pages/index.ts
index 371eed61d..3554c4b95 100644
--- a/config-ui/src/pages/index.ts
+++ b/config-ui/src/pages/index.ts
@@ -18,7 +18,5 @@
export * from './blueprint';
export * from './connection';
-export * from './db-migrate';
-export * from './offline';
export * from './pipeline';
export * from './project';
diff --git a/config-ui/src/routes/error/components/exception/index.tsx
b/config-ui/src/routes/error/components/exception/index.tsx
new file mode 100644
index 000000000..d2aca5c55
--- /dev/null
+++ b/config-ui/src/routes/error/components/exception/index.tsx
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { useNavigate } from 'react-router-dom';
+import { Icon, Colors, Button, Intent } from '@blueprintjs/core';
+
+import { Card, Buttons } from '@/components';
+
+interface Props {
+ error: string | Error;
+}
+
+export const Exception = ({ error }: Props) => {
+ const navigate = useNavigate();
+ const handleResetError = () => navigate('/');
+
+ return (
+ <Card>
+ <h2>
+ <Icon icon="error" color={Colors.RED5} size={20} />
+ <span>{error.toString() || 'Unknown Error'}</span>
+ </h2>
+ <p>
+ Please try again, if the problem persists include the above error
message when filing a bug report on{' '}
+ <strong>GitHub</strong>. You can also message us on
<strong>Slack</strong> to engage with community members for
+ solutions to common issues.
+ </p>
+ <Buttons position="bottom" align="center">
+ <Button text="Continue" intent={Intent.PRIMARY}
onClick={handleResetError} />
+ <Button
+ text="Visit GitHub"
+ onClick={() =>
window.open('https://github.com/apache/incubator-devlake', '_blank',
'noopener,noreferrer')}
+ />
+ </Buttons>
+ </Card>
+ );
+};
diff --git a/config-ui/src/layouts/index.ts
b/config-ui/src/routes/error/components/index.ts
similarity index 89%
copy from config-ui/src/layouts/index.ts
copy to config-ui/src/routes/error/components/index.ts
index 7e43f3d53..6bbf39072 100644
--- a/config-ui/src/layouts/index.ts
+++ b/config-ui/src/routes/error/components/index.ts
@@ -16,5 +16,6 @@
*
*/
-export * from './base';
-export * from './error';
+export * from './exception';
+export * from './needs-db-migrate';
+export * from './offline';
diff --git a/config-ui/src/pages/db-migrate/api.ts
b/config-ui/src/routes/error/components/needs-db-migrate/api.ts
similarity index 100%
rename from config-ui/src/pages/db-migrate/api.ts
rename to config-ui/src/routes/error/components/needs-db-migrate/api.ts
diff --git a/config-ui/src/pages/db-migrate/index.tsx
b/config-ui/src/routes/error/components/needs-db-migrate/index.tsx
similarity index 98%
rename from config-ui/src/pages/db-migrate/index.tsx
rename to config-ui/src/routes/error/components/needs-db-migrate/index.tsx
index 2e74854d6..fb196794c 100644
--- a/config-ui/src/pages/db-migrate/index.tsx
+++ b/config-ui/src/routes/error/components/needs-db-migrate/index.tsx
@@ -25,7 +25,7 @@ import { operator } from '@/utils';
import * as API from './api';
-export const DBMigratePage = () => {
+export const NeedsDBMigrate = () => {
const [operating, setOperating] = useState(false);
const navigate = useNavigate();
diff --git a/config-ui/src/pages/offline/api.ts
b/config-ui/src/routes/error/components/offline/api.ts
similarity index 100%
copy from config-ui/src/pages/offline/api.ts
copy to config-ui/src/routes/error/components/offline/api.ts
diff --git a/config-ui/src/pages/offline/index.tsx
b/config-ui/src/routes/error/components/offline/index.tsx
similarity index 98%
rename from config-ui/src/pages/offline/index.tsx
rename to config-ui/src/routes/error/components/offline/index.tsx
index 544283090..37b39aee8 100644
--- a/config-ui/src/pages/offline/index.tsx
+++ b/config-ui/src/routes/error/components/offline/index.tsx
@@ -26,7 +26,7 @@ import { useAutoRefresh } from '@/hooks';
import * as API from './api';
-export const OfflinePage = () => {
+export const Offline = () => {
const [version, setVersion] = useState(1);
const navigate = useNavigate();
diff --git a/config-ui/src/layouts/error/index.tsx
b/config-ui/src/routes/error/error.tsx
similarity index 64%
rename from config-ui/src/layouts/error/index.tsx
rename to config-ui/src/routes/error/error.tsx
index 40fcbee0f..28bf80715 100644
--- a/config-ui/src/layouts/error/index.tsx
+++ b/config-ui/src/routes/error/error.tsx
@@ -16,18 +16,24 @@
*
*/
-import { Outlet } from 'react-router-dom';
+import { useRouteError, isRouteErrorResponse } from 'react-router-dom';
import { Logo } from '@/components';
+import { ErrorEnum } from './types';
+import { Offline, NeedsDBMigrate, Exception } from './components';
import * as S from './styled';
-export const ErrorLayout = () => {
+export const Error = () => {
+ const error = useRouteError() as Error;
+
return (
<S.Wrapper>
<Logo />
<S.Inner>
- <Outlet />
+ {isRouteErrorResponse(error) && error.data.error ===
ErrorEnum.API_OFFLINE && <Offline />}
+ {isRouteErrorResponse(error) && error.data.error ===
ErrorEnum.NEEDS_DB_MIRGATE && <NeedsDBMigrate />}
+ {!isRouteErrorResponse(error) && <Exception error={error} />}
</S.Inner>
</S.Wrapper>
);
diff --git a/config-ui/src/layouts/index.ts
b/config-ui/src/routes/error/index.ts
similarity index 97%
copy from config-ui/src/layouts/index.ts
copy to config-ui/src/routes/error/index.ts
index 7e43f3d53..03f1eec15 100644
--- a/config-ui/src/layouts/index.ts
+++ b/config-ui/src/routes/error/index.ts
@@ -16,5 +16,5 @@
*
*/
-export * from './base';
+export * from './types';
export * from './error';
diff --git a/config-ui/src/routes/error/index.tsx
b/config-ui/src/routes/error/index.tsx
deleted file mode 100644
index 25a79fb59..000000000
--- a/config-ui/src/routes/error/index.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import { useRouteError, useNavigate } from 'react-router-dom';
-import { Icon, Button, Colors, Intent } from '@blueprintjs/core';
-
-import { Logo, Card, Buttons } from '@/components';
-
-import * as S from './styled';
-
-export const Error = () => {
- const error = useRouteError() as Error;
- const navigate = useNavigate();
-
- const handleResetError = () => navigate('/');
-
- return (
- <S.Wrapper>
- <Logo />
- <S.Inner>
- <Card>
- <h2>
- <Icon icon="error" color={Colors.RED5} size={20} />
- <span>{error.toString() || 'Unknown Error'}</span>
- </h2>
- <p>
- Please try again, if the problem persists include the above error
message when filing a bug report on{' '}
- <strong>GitHub</strong>. You can also message us on
<strong>Slack</strong> to engage with community members
- for solutions to common issues.
- </p>
- <Buttons position="bottom" align="center">
- <Button text="Continue" intent={Intent.PRIMARY}
onClick={handleResetError} />
- <Button
- text="Visit GitHub"
- onClick={() =>
- window.open('https://github.com/apache/incubator-devlake',
'_blank', 'noopener,noreferrer')
- }
- />
- </Buttons>
- </Card>
- </S.Inner>
- </S.Wrapper>
- );
-};
diff --git a/config-ui/src/pages/offline/api.ts
b/config-ui/src/routes/error/types.ts
similarity index 89%
rename from config-ui/src/pages/offline/api.ts
rename to config-ui/src/routes/error/types.ts
index 38f8e0fed..74b9048b1 100644
--- a/config-ui/src/pages/offline/api.ts
+++ b/config-ui/src/routes/error/types.ts
@@ -16,6 +16,7 @@
*
*/
-import { request } from '@/utils';
-
-export const ping = () => request('/ping');
+export enum ErrorEnum {
+ API_OFFLINE = 'API_OFFLINE',
+ NEEDS_DB_MIRGATE = 'NEEDS_DB_MIRGATE',
+}
diff --git a/config-ui/src/utils/request.ts b/config-ui/src/utils/request.ts
index 9da4ea9cf..cd57e6f16 100644
--- a/config-ui/src/utils/request.ts
+++ b/config-ui/src/utils/request.ts
@@ -25,19 +25,6 @@ const instance = axios.create({
baseURL: DEVLAKE_ENDPOINT,
});
-instance.interceptors.response.use(
- (response) => response,
- (error) => {
- const status = error.response?.status;
-
- if (status === 428) {
- window.location.replace('/db-migrate');
- }
-
- return Promise.reject(error);
- },
-);
-
export type RequestConfig = {
baseURL?: string;
method?: AxiosRequestConfig['method'];