@@ -2,7 +2,7 @@ import {DataLoader} from 'argo-ui';
2
2
import * as classNames from 'classnames' ;
3
3
import * as React from 'react' ;
4
4
import { useEffect , useState , useRef } from 'react' ;
5
- import { bufferTime , delay , retryWhen } from 'rxjs/operators' ;
5
+ import { bufferTime , catchError , delay , retryWhen } from 'rxjs/operators' ;
6
6
7
7
import { LogEntry } from '../../../shared/models' ;
8
8
import { services , ViewPreferences } from '../../../shared/services' ;
@@ -27,6 +27,7 @@ import {PodNamesToggleButton} from './pod-names-toggle-button';
27
27
import { AutoScrollButton } from './auto-scroll-button' ;
28
28
import { WrapLinesButton } from './wrap-lines-button' ;
29
29
import Ansi from 'ansi-to-react' ;
30
+ import { EMPTY } from 'rxjs' ;
30
31
31
32
export interface PodLogsProps {
32
33
namespace : string ;
@@ -95,6 +96,7 @@ export const PodsLogsViewer = (props: PodLogsProps) => {
95
96
const [ logs , setLogs ] = useState < LogEntry [ ] > ( [ ] ) ;
96
97
const logsContainerRef = useRef ( null ) ;
97
98
const uniquePods = Array . from ( new Set ( logs . map ( log => log . podName ) ) ) ;
99
+ const [ errorMessage , setErrorMessage ] = useState < string | null > ( null ) ;
98
100
99
101
const setWithQueryParams = < T extends ( val : any ) => void > ( key : string , cb : T ) => {
100
102
return ( val => {
@@ -155,9 +157,20 @@ export const PodsLogsViewer = (props: PodLogsProps) => {
155
157
sinceSeconds,
156
158
filter,
157
159
previous
158
- } ) // accumulate log changes and render only once every 100ms to reduce CPU usage
159
- . pipe ( bufferTime ( 100 ) )
160
- . pipe ( retryWhen ( errors => errors . pipe ( delay ( 500 ) ) ) )
160
+ } )
161
+ . pipe (
162
+ bufferTime ( 100 ) ,
163
+ catchError ( ( error : any ) => {
164
+ const errorBody = JSON . parse ( error . body ) ;
165
+ if ( errorBody . error && errorBody . error . message ) {
166
+ if ( errorBody . error . message . includes ( 'max pods to view logs are reached' ) ) {
167
+ setErrorMessage ( 'Max pods to view logs are reached. Please provide more granular query.' ) ;
168
+ return EMPTY ; // Non-retryable condition, stop the stream and display the error message.
169
+ }
170
+ }
171
+ } ) ,
172
+ retryWhen ( errors => errors . pipe ( delay ( 500 ) ) )
173
+ )
161
174
. subscribe ( log => setLogs ( previousLogs => previousLogs . concat ( log ) ) ) ;
162
175
163
176
return ( ) => logsSource . unsubscribe ( ) ;
@@ -268,7 +281,11 @@ export const PodsLogsViewer = (props: PodLogsProps) => {
268
281
</ span >
269
282
</ div >
270
283
< div className = { classNames ( 'pod-logs-viewer' , { 'pod-logs-viewer--inverted' : prefs . appDetails . darkMode } ) } onWheel = { handleScroll } >
271
- < AutoSizer > { ( { width, height} : { width : number ; height : number } ) => logsContent ( width , height , prefs . appDetails . wrapLines , prefs ) } </ AutoSizer >
284
+ { errorMessage ? (
285
+ < div > { errorMessage } </ div >
286
+ ) : (
287
+ < AutoSizer > { ( { width, height} : { width : number ; height : number } ) => logsContent ( width , height , prefs . appDetails . wrapLines , prefs ) } </ AutoSizer >
288
+ ) }
272
289
</ div >
273
290
</ React . Fragment >
274
291
) ;
0 commit comments