Skip to content

Commit a2b4262

Browse files
committed
Error in UI
1 parent 78965ed commit a2b4262

File tree

6 files changed

+112
-4
lines changed

6 files changed

+112
-4
lines changed

src/containers/Tenant/Diagnostics/Overview/Overview.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ function Overview({type, path, database}: OverviewProps) {
9595
[EPathType.EPathTypeExternalDataSource]: () => <ExternalDataSourceInfo data={data} />,
9696
[EPathType.EPathTypeView]: () => <ViewInfo data={data} />,
9797
[EPathType.EPathTypeReplication]: () => <AsyncReplicationInfo data={data} />,
98-
[EPathType.EPathTypeTransfer]: () => <TransferInfo data={data} />,
98+
[EPathType.EPathTypeTransfer]: () => (
99+
<TransferInfo path={path} database={database} data={data} />
100+
),
99101
};
100102

101103
return (type && pathTypeToComponent[type]?.()) || <TableInfo data={data} type={type} />;

src/containers/Tenant/Diagnostics/Overview/TransferInfo/TransferInfo.tsx

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ import {Flex, Text} from '@gravity-ui/uikit';
44
import {AsyncReplicationState} from '../../../../../components/AsyncReplicationState';
55
import {YDBSyntaxHighlighter} from '../../../../../components/SyntaxHighlighter/YDBSyntaxHighlighter';
66
import {YDBDefinitionList} from '../../../../../components/YDBDefinitionList/YDBDefinitionList';
7+
import {replicationApi} from '../../../../../store/reducers/replication';
78
import type {TEvDescribeSchemeResult} from '../../../../../types/api/schema';
89
import {getEntityName} from '../../../utils';
910

1011
import {Credentials} from './Credentials';
1112
import i18n from './i18n';
1213

1314
interface TransferProps {
15+
path: string;
16+
database: string;
1417
data?: TEvDescribeSchemeResult;
1518
}
1619

1720
/** Displays overview for Transfer EPathType */
18-
export function TransferInfo({data}: TransferProps) {
21+
export function TransferInfo({path, database, data}: TransferProps) {
1922
const entityName = getEntityName(data?.PathDescription);
2023

2124
if (!data) {
@@ -26,7 +29,7 @@ export function TransferInfo({data}: TransferProps) {
2629
);
2730
}
2831

29-
const transferItems = prepareTransferItems(data);
32+
const transferItems = prepareTransferItems(path, database, data);
3033

3134
return (
3235
<Flex direction="column" gap="4">
@@ -35,7 +38,29 @@ export function TransferInfo({data}: TransferProps) {
3538
);
3639
}
3740

38-
function prepareTransferItems(data: TEvDescribeSchemeResult) {
41+
function prepareErrors(path: string, database: string) {
42+
const {data, error} = replicationApi.useGetReplicationQuery({path, database}, {});
43+
44+
if (data?.error?.issues) {
45+
return (
46+
<Text variant="code-inline-2" color="danger">
47+
{data.error.issues[0].message}
48+
</Text>
49+
);
50+
}
51+
52+
if (error) {
53+
return (
54+
<Text variant="code-inline-2" color="danger">
55+
Error
56+
</Text>
57+
);
58+
}
59+
60+
return '';
61+
}
62+
63+
function prepareTransferItems(path: string, database: string, data: TEvDescribeSchemeResult) {
3964
const transferDescription = data.PathDescription?.ReplicationDescription || {};
4065
const state = transferDescription.State;
4166
const srcConnectionParams = transferDescription.Config?.SrcConnectionParams || {};
@@ -44,6 +69,7 @@ function prepareTransferItems(data: TEvDescribeSchemeResult) {
4469
const srcPath = target?.SrcPath;
4570
const dstPath = target?.DstPath;
4671
const transformLambda = target?.TransformLambda;
72+
const errors = prepareErrors(path, database);
4773

4874
const info: DefinitionListItem[] = [];
4975

@@ -54,6 +80,13 @@ function prepareTransferItems(data: TEvDescribeSchemeResult) {
5480
});
5581
}
5682

83+
if (errors) {
84+
info.push({
85+
name: i18n('state.error'),
86+
content: errors,
87+
});
88+
}
89+
5790
if (Endpoint) {
5891
info.push({
5992
name: i18n('srcConnection.endpoint.label'),

src/containers/Tenant/Diagnostics/Overview/TransferInfo/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"srcConnection.database.label": "Source Database Path",
55
"srcConnection.endpoint.label": "Source Cluster Endpoint",
66
"state.label": "State",
7+
"state.error": "Error",
78
"srcPath.label": "Source Topic",
89
"dstPath.label": "Destination Table",
910
"transformLambda.label": "Transformation Lambda"

src/services/api/viewer.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import type {
1818
SendQueryParams,
1919
} from '../../types/api/query';
2020
import type {JsonRenderRequestParams, JsonRenderResponse} from '../../types/api/render';
21+
import type {DescribeReplicationResult} from '../../types/api/replication';
2122
import type {TEvDescribeSchemeResult} from '../../types/api/schema';
2223
import type {StorageRequestParams, TStorageInfo} from '../../types/api/storage';
2324
import type {TEvSystemStateResponse} from '../../types/api/systemState';
@@ -229,6 +230,22 @@ export class ViewerAPI extends BaseYdbAPI {
229230
);
230231
}
231232

233+
getReplication(
234+
{path, database}: {path: string; database: string},
235+
{concurrentId, signal}: AxiosOptions = {},
236+
) {
237+
return this.get<DescribeReplicationResult>(
238+
this.getPath('/viewer/json/describe_replication'),
239+
{
240+
enums: true,
241+
include_stats: true,
242+
database,
243+
path,
244+
},
245+
{concurrentId, requestConfig: {signal}},
246+
);
247+
}
248+
232249
getTopic(
233250
{path, database}: {path: string; database: string},
234251
{concurrentId, signal}: AxiosOptions = {},

src/store/reducers/replication.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* eslint-disable camelcase */
2+
3+
import {api} from './api';
4+
5+
export const replicationApi = api.injectEndpoints({
6+
endpoints: (build) => ({
7+
getReplication: build.query({
8+
queryFn: async (params: {path: string; database: string}) => {
9+
try {
10+
const data = await window.api.viewer.getReplication(params);
11+
// On older version it can return HTML page of Developer UI with an error
12+
if (typeof data !== 'object') {
13+
return {error: {}};
14+
}
15+
return {data};
16+
} catch (error) {
17+
return {error};
18+
}
19+
},
20+
providesTags: ['All'],
21+
}),
22+
}),
23+
overrideExisting: 'throw',
24+
});

src/types/api/replication.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* eslint-disable camelcase */
2+
3+
import type {TIssueMessage} from './operations';
4+
5+
/**
6+
* endpoint: /json/describe_replication
7+
*
8+
* source: https://github.com/ydb-platform/ydb/blob/main/ydb/public/api/protos/draft/ydb_replication.proto
9+
*
10+
* Original proto file doesn't specify optional fields, so every field is considered optional
11+
*/
12+
export interface DescribeReplicationResult {
13+
items?: TReplicationItems;
14+
15+
error?: TReplicationErrorState;
16+
}
17+
18+
export interface TReplicationErrorState {
19+
issues?: TIssueMessage[];
20+
}
21+
22+
export interface TReplicationItems {
23+
items?: TReplicationItem[];
24+
}
25+
26+
export interface TReplicationItem {
27+
id?: string;
28+
source_path?: string;
29+
destination_path?: string;
30+
source_changefeed_name?: string;
31+
}

0 commit comments

Comments
 (0)