1
0
mirror of https://github.com/quay/quay.git synced 2026-01-26 06:21:37 +03:00

ui: rendering error for splunk logs (PROJQUAY-6934) (#4558)

This commit is contained in:
Brandon Caton
2025-11-18 16:07:09 -05:00
committed by GitHub
parent db275c441b
commit a9d2d89505
4 changed files with 94 additions and 7 deletions

View File

@@ -260,6 +260,33 @@ describe('Usage Logs', () => {
cy.contains('No data to display.').should('be.visible');
});
it('shows Splunk error message when logs are not implemented', () => {
// Mock 501 NOT IMPLEMENTED error from Splunk
cy.intercept('GET', '/api/v1/organization/projectquay/aggregatelogs?*', {
statusCode: 501,
body: {
message: 'Method not implemented, Splunk does not support log lookups',
},
}).as('aggregateLogsError');
cy.intercept('GET', '/api/v1/organization/projectquay/logs?*', {
statusCode: 501,
body: {
message: 'Method not implemented, Splunk does not support log lookups',
},
}).as('logsError');
cy.visit('/organization/projectquay?tab=Logs');
// Verify the specific Splunk error message is displayed (not generic error)
cy.contains(
'Method not implemented, Splunk does not support log lookups',
).should('be.visible');
// Verify generic error is NOT displayed
cy.contains('Unable to complete request').should('not.exist');
});
it('filter logs', () => {
cy.intercept('GET', '/api/v1/organization/projectquay/logs?*', logsResp);
@@ -625,4 +652,31 @@ describe('Usage Logs - Superuser', () => {
cy.contains('th', 'Performed by').should('be.visible');
cy.contains('th', 'IP Address').should('be.visible');
});
it('shows Splunk error message on superuser page when logs are not implemented', () => {
// Mock 501 NOT IMPLEMENTED error from Splunk
cy.intercept('GET', '/api/v1/superuser/aggregatelogs?*', {
statusCode: 501,
body: {
message: 'Method not implemented, Splunk does not support log lookups',
},
}).as('aggregateLogsError');
cy.intercept('GET', '/api/v1/superuser/logs?*', {
statusCode: 501,
body: {
message: 'Method not implemented, Splunk does not support log lookups',
},
}).as('logsError');
cy.visit('/usage-logs');
// Verify the specific Splunk error message is displayed (not generic error)
cy.contains(
'Method not implemented, Splunk does not support log lookups',
).should('be.visible');
// Verify generic error is NOT displayed
cy.contains('Unable to complete request').should('not.exist');
});
});

View File

@@ -18,15 +18,19 @@ export default function RequestError(props: RequestErrorProps) {
const errorMessage = props.message || getErrorMessageFromUnknown(props.err);
const message = capitalizeFirstLetter(errorMessage);
const title =
props.title !== undefined ? props.title : 'Unable to complete request';
return (
<PageSection variant={PageSectionVariants.light}>
<EmptyState variant="full">
<EmptyStateHeader
titleText="Unable to complete request"
icon={<EmptyStateIcon icon={ExclamationTriangleIcon} />}
headingLevel="h1"
/>
{title && (
<EmptyStateHeader
titleText={title}
icon={<EmptyStateIcon icon={ExclamationTriangleIcon} />}
headingLevel="h1"
/>
)}
<EmptyStateBody>{message}</EmptyStateBody>
<EmptyStateFooter>
<Button title="Home" onClick={() => window.location.reload()}>
@@ -41,4 +45,5 @@ export default function RequestError(props: RequestErrorProps) {
interface RequestErrorProps {
err?: unknown;
message?: string;
title?: string;
}

View File

@@ -12,6 +12,7 @@ import {useQuery} from '@tanstack/react-query';
import RequestError from 'src/components/errors/RequestError';
import {Flex, FlexItem, Spinner} from '@patternfly/react-core';
import {logKinds} from './UsageLogs';
import {AxiosError} from 'axios';
import './css/UsageLogs.scss';
@@ -53,6 +54,7 @@ export default function UsageLogsGraph(props: UsageLogsGraphProps) {
const {
data: aggregateLogs,
isError: errorFetchingLogs,
error: fetchError,
isLoading: loadingAggregateLogs,
} = useQuery(
[
@@ -79,8 +81,20 @@ export default function UsageLogsGraph(props: UsageLogsGraphProps) {
// tslint:disable-next-line:curly
if (loadingAggregateLogs) return <Spinner />;
// tslint:disable-next-line:curly
if (errorFetchingLogs) return <RequestError message="Unable to get logs" />;
if (errorFetchingLogs) {
// Check if this is a 501 NOT IMPLEMENTED error from Splunk
if (
fetchError instanceof AxiosError &&
fetchError.response?.status === 501
) {
const errorMessage =
fetchError.response?.data?.message || 'Unable to get logs';
return <RequestError message={errorMessage} title="" />;
}
return <RequestError message="Unable to get logs" />;
}
let maxRange = 0;

View File

@@ -25,6 +25,7 @@ import {usePaginatedSortableTable} from '../../hooks/usePaginatedSortableTable';
import {ToolbarPagination} from 'src/components/toolbar/ToolbarPagination';
import {extractTextFromReactNode} from 'src/libs/utils';
import {useState, useMemo, useEffect, useRef} from 'react';
import {AxiosError} from 'axios';
interface LogEntry {
datetime: string;
@@ -87,6 +88,7 @@ export function UsageLogsTable(props: UsageLogsTableProps) {
data: logs,
isLoading: loadingLogs,
isError: errorLogs,
error: fetchError,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
@@ -197,7 +199,19 @@ export function UsageLogsTable(props: UsageLogsTableProps) {
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
if (loadingLogs) return <Spinner />;
if (errorLogs) return <RequestError message="Unable to retrieve logs" />;
if (errorLogs) {
// Check if this is a 501 NOT IMPLEMENTED error from Splunk
if (
fetchError instanceof AxiosError &&
fetchError.response?.status === 501
) {
const errorMessage =
fetchError.response?.data?.message || 'Unable to retrieve logs';
return <RequestError message={errorMessage} title="" />;
}
return <RequestError message="Unable to retrieve logs" />;
}
return (
<>