Skip to content

Commit

Permalink
Render errors when getting a list of dags (apache#42897)
Browse files Browse the repository at this point in the history
* Render errors when getting a list of dags

* Restore axios, prettierignore pnpm-store

* Add pnpm-store to prettier ignore
  • Loading branch information
bbovenzi authored and harjeevanmaan committed Oct 23, 2024
1 parent b3e4636 commit f99d1fb
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 10 deletions.
1 change: 1 addition & 0 deletions airflow/ui/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ dist/
*.md
*.yaml
coverage/*
.pnpm-store
8 changes: 4 additions & 4 deletions airflow/ui/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions airflow/ui/src/components/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type DataTableProps<TData> = {
readonly columns: Array<MetaColumn<TData>>;
readonly data: Array<TData>;
readonly displayMode?: "card" | "table";
readonly errorMessage?: ReactNode | string;
readonly getRowCanExpand?: (row: Row<TData>) => boolean;
readonly initialState?: TableState;
readonly isFetching?: boolean;
Expand All @@ -62,6 +63,7 @@ export const DataTable = <TData,>({
columns,
data,
displayMode = "table",
errorMessage,
getRowCanExpand = defaultGetRowCanExpand,
initialState,
isFetching,
Expand Down Expand Up @@ -127,10 +129,9 @@ export const DataTable = <TData,>({
Boolean(isFetching) && !Boolean(isLoading) ? "visible" : "hidden"
}
/>
{errorMessage}
{!Boolean(isLoading) && !rows.length && (
<Text fontSize="small">
{noRowsMessage ?? `No ${modelName}s found.`}
</Text>
<Text pt={1}>{noRowsMessage ?? `No ${modelName}s found.`}</Text>
)}
{display === "table" && <TableList table={table} />}
{display === "card" && cardDef !== undefined && (
Expand Down
67 changes: 67 additions & 0 deletions airflow/ui/src/components/ErrorAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*!
* 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 { Alert, AlertIcon } from "@chakra-ui/react";
import type { ApiError } from "openapi-gen/requests/core/ApiError";
import type {
HTTPExceptionResponse,
HTTPValidationError,
} from "openapi-gen/requests/types.gen";

type ExpandedApiError = {
body: HTTPExceptionResponse | HTTPValidationError;
} & ApiError;

type Props = {
readonly error?: unknown;
};

export const ErrorAlert = ({ error: err }: Props) => {
const error = err as ExpandedApiError;

if (!Boolean(error)) {
return undefined;
}

const details = error.body.detail;
let detailMessage;

if (details !== undefined) {
if (typeof details === "string") {
detailMessage = details;
} else if (Array.isArray(details)) {
detailMessage = details.map(
(detail) => `
${detail.loc.join(".")} ${detail.msg}`,
);
} else {
detailMessage = Object.keys(details).map(
(key) => `${key}: ${details[key] as string}`,
);
}
}

return (
<Alert status="error">
<AlertIcon />
{error.message}
<br />
{detailMessage}
</Alert>
);
};
6 changes: 4 additions & 2 deletions airflow/ui/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
import { ChakraProvider } from "@chakra-ui/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import axios, { type AxiosError, type AxiosResponse } from "axios";
import axios, { type AxiosError } from "axios";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";

Expand All @@ -45,14 +45,16 @@ const queryClient = new QueryClient({

// redirect to login page if the API responds with unauthorized or forbidden errors
axios.interceptors.response.use(
(response: AxiosResponse) => response,
(response) => response,
(error: AxiosError) => {
if (error.response?.status === 403 || error.response?.status === 401) {
const params = new URLSearchParams();

params.set("next", globalThis.location.href);
globalThis.location.replace(`/login?${params.toString()}`);
}

return Promise.reject(error);
},
);

Expand Down
4 changes: 3 additions & 1 deletion airflow/ui/src/pages/DagsList/DagsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { DataTable } from "src/components/DataTable";
import { ToggleTableDisplay } from "src/components/DataTable/ToggleTableDisplay";
import type { CardDef } from "src/components/DataTable/types";
import { useTableURLState } from "src/components/DataTable/useTableUrlState";
import { ErrorAlert } from "src/components/ErrorAlert";
import { SearchBar } from "src/components/SearchBar";
import { TogglePause } from "src/components/TogglePause";
import { pluralize } from "src/utils/pluralize";
Expand Down Expand Up @@ -113,7 +114,7 @@ export const DagsList = () => {
const [sort] = sorting;
const orderBy = sort ? `${sort.desc ? "-" : ""}${sort.id}` : undefined;

const { data, isFetching, isLoading } = useDagServiceGetDags({
const { data, error, isFetching, isLoading } = useDagServiceGetDags({
lastDagRunState,
limit: pagination.pageSize,
offset: pagination.pageIndex * pagination.pageSize,
Expand Down Expand Up @@ -169,6 +170,7 @@ export const DagsList = () => {
columns={columns}
data={data?.dags ?? []}
displayMode={display}
errorMessage={<ErrorAlert error={error} />}
initialState={tableURLState}
isFetching={isFetching}
isLoading={isLoading}
Expand Down

0 comments on commit f99d1fb

Please sign in to comment.