@@ -57,8 +57,8 @@ export const UserContext = React.createContext<IUserContextInterface>({
5757} ) ;
5858
5959const UserProvider : React . FC < { children : any } > = ( { children} ) => {
60-
6160 const [ user , setUser ] = useState < UserContextInterface > ( defaultUserData ) ;
61+ const [ encounteredErrors , setEncounteredErrors ] = useState < string [ ] > ( [ ] ) ;
6262 const [ stompMessageSubscription , setStompMessageSubscription ] = useState < Subscription | null > ( null ) ;
6363 const [ unsubscribeId , setUnsubscribeId ] = useState < string | null > ( null ) ;
6464 const sessionUser = localStorage . getItem ( "dataHubUser" ) ;
@@ -68,6 +68,37 @@ const UserProvider: React.FC<{ children: any }> = ({children}) => {
6868 initialTimeoutDate . setSeconds ( initialTimeoutDate . getSeconds ( ) + MAX_SESSION_TIME ) ;
6969 const sessionTimeoutDate = useRef < Date > ( initialTimeoutDate ) ;
7070
71+ const getConfigHash = ( config ) => {
72+ return CryptoJS . SHA256 ( `${ config . method } :${ config . url } :${ config . data } ` ) . toString ( ) ;
73+ } ;
74+
75+ axios . interceptors . request . use (
76+ request => {
77+ if ( request ) {
78+ const requestHash = getConfigHash ( request ) ;
79+ if ( encounteredErrors . includes ( requestHash ) ) {
80+ throw new axios . Cancel ( requestHash ) ;
81+ }
82+ }
83+ return request ;
84+ } ,
85+ error => {
86+ if ( error instanceof axios . Cancel && encounteredErrors . includes ( error . message ) ) {
87+ return new Promise ( r => setTimeout ( r , 5000 ) ) . then (
88+ ( r ) => {
89+ // forget the error after 5 seconds.
90+ if ( encounteredErrors . includes ( error . message ) ) {
91+ encounteredErrors . splice ( encounteredErrors . indexOf ( error . message ) , 1 ) ;
92+ setEncounteredErrors ( encounteredErrors ) ;
93+ }
94+ return r ;
95+ }
96+ ) ;
97+ }
98+ return Promise . reject ( error ) ;
99+ }
100+ ) ;
101+
71102 const setSessionTimeoutDate = ( timeInSeconds ) => {
72103 const timeoutDate = new Date ( ) ;
73104 timeoutDate . setSeconds ( timeoutDate . getSeconds ( ) + timeInSeconds ) ;
@@ -202,94 +233,130 @@ const UserProvider: React.FC<{ children: any }> = ({children}) => {
202233 localStorage . setItem ( "loginResp" , "" ) ;
203234 localStorage . setItem ( "hubCentralSessionToken" , "" ) ;
204235 authoritiesService . setAuthorities ( [ ] ) ;
236+ setEncounteredErrors ( [ ] ) ;
205237 resetEnvironment ( ) ;
206238 } ) ;
207239 } ;
208240
241+ /*
242+ * handleError - A consistent way to handle and present errors.
243+ * @param error - The error response which we will decide to handle an error
244+ * */
209245 const handleError = ( error ) => {
210246 const DEFAULT_MESSAGE = "Internal Server Error" ;
211- switch ( error . response . status ) {
212- case 401 : {
213- localStorage . setItem ( "dataHubUser" , "" ) ;
214- localStorage . setItem ( "loginResp" , "" ) ;
215- setUser ( { ...user , name : "" , authenticated : false } ) ;
216- break ;
217- }
218- case 400 :
219- case 403 :
220- case 405 :
221- case 408 :
222- case 414 : {
223- console . error ( "HTTP ERROR" , error . response ) ;
224- let title = error . response . status + " " + error . response . statusText ;
225- let message = DEFAULT_MESSAGE ;
226-
227- if ( error . response . data . hasOwnProperty ( "message" ) ) {
228- message = error . response . data . message ;
247+ let errorHash = "" ;
248+ let errorAlreadyEncountered = false ;
249+ if ( error . config && error . response && error . response . status >= 500 ) {
250+ let config = error . config ;
251+ errorHash = getConfigHash ( config ) ;
252+ errorAlreadyEncountered = encounteredErrors . includes ( errorHash ) ;
253+ if ( ! errorAlreadyEncountered ) {
254+ console . warn ( "Request error will cause future exact requests to be canceled for the next 5 seconds." ) ;
255+ encounteredErrors . push ( errorHash ) ;
256+ setEncounteredErrors ( encounteredErrors ) ;
229257 }
230- setUser ( {
231- ...user ,
232- error : {
233- title : title ,
234- message : message ,
235- type : "ALERT"
236- }
237- } ) ;
238- break ;
239258 }
240- case 404 : {
241- setUser ( {
242- ... user ,
243- // redirect: true,
244- error : {
245- title : error . response . data . error ,
246- message : error . response . data . message || DEFAULT_MESSAGE ,
247- type : "ALERT"
259+ if ( ! errorAlreadyEncountered ) {
260+ if ( error . response ) {
261+ switch ( error . response . status ) {
262+ case 401 : {
263+ localStorage . setItem ( "dataHubUser" , "" ) ;
264+ localStorage . setItem ( "loginResp" , "" ) ;
265+ setUser ( { ... user , name : "" , authenticated : false } ) ;
266+ break ;
248267 }
249- } ) ;
250- break ;
251- }
252- case 500 :
253- case 501 :
254- case 502 :
255- case 503 :
256- case 504 :
257- case 505 :
258- case 511 : {
259- console . error ( "HTTP ERROR " , error . response ) ;
260- let title = error . response . status + " " + error . response . statusText ;
261- let message = DEFAULT_MESSAGE ;
268+ case 400 :
269+ case 403 :
270+ case 405 :
271+ case 408 :
272+ case 414 : {
273+ console . error ( "HTTP ERROR" , error . response ) ;
274+ let title = error . response . status + " " + error . response . statusText ;
275+ let message = DEFAULT_MESSAGE ;
262276
263- if ( error . response . data . hasOwnProperty ( "message" ) ) {
264- message = error . response . data . message ;
265- }
266- setUser ( {
267- ...user ,
268- error : {
269- title,
270- message,
271- type : "MODAL"
277+ if ( error . response . data . hasOwnProperty ( "message" ) ) {
278+ message = error . response . data . message ;
279+ }
280+ setUser ( {
281+ ...user ,
282+ error : {
283+ title : title ,
284+ message : message ,
285+ type : "ALERT" ,
286+ encounteredErrors
287+ }
288+ } ) ;
289+ break ;
272290 }
273- } ) ;
274- break ;
275- }
276- default : {
277- console . error ( "HTTP ERROR " , error . response ) ;
291+ case 404 : {
292+ setUser ( {
293+ ...user ,
294+ // redirect: true,
295+ error : {
296+ title : error . response . data . error ,
297+ message : error . response . data . message || DEFAULT_MESSAGE ,
298+ type : "ALERT" ,
299+ encounteredErrors
300+ }
301+ } ) ;
302+ break ;
303+ }
304+ case 500 :
305+ case 501 :
306+ case 502 :
307+ case 503 :
308+ case 504 :
309+ case 505 :
310+ case 511 : {
311+ console . error ( "HTTP ERROR " , error . response ) ;
312+ let title = error . response . status + " " + error . response . statusText ;
313+ let message = DEFAULT_MESSAGE ;
278314
279- setUser ( {
280- ...user ,
281- error : {
282- title : DEFAULT_MESSAGE ,
283- message : "Please check the console for more information" ,
284- type : "MODAL"
315+ if ( error . response . data . hasOwnProperty ( "message" ) ) {
316+ message = error . response . data . message ;
317+ }
318+ setUser ( {
319+ ...user ,
320+ error : {
321+ title,
322+ message,
323+ type : "MODAL" ,
324+ encounteredErrors
325+ }
326+ } ) ;
327+ break ;
285328 }
286- } ) ;
287- break ;
288- }
329+ default : {
330+ console . error ( "HTTP ERROR " , error . response ) ;
331+ setUser ( {
332+ ...user ,
333+ error : {
334+ title : DEFAULT_MESSAGE ,
335+ message : "Please check the console for more information" ,
336+ type : "MODAL" ,
337+ encounteredErrors
338+ }
339+ } ) ;
340+ break ;
341+ }
342+ }
343+ } else {
344+ console . error ( "ERROR " , error ) ;
345+ setUser ( {
346+ ...user ,
347+ error : {
348+ title : DEFAULT_MESSAGE ,
349+ message : "Please check the console for more information" ,
350+ type : "MODAL" ,
351+ encounteredErrors
352+ }
353+ } ) ;
354+ }
289355 }
290356 } ;
291357
292358 const clearErrorMessage = ( ) => {
359+ setEncounteredErrors ( [ ] ) ;
293360 setUser ( { ...user , error : { title : "" , message : "" , type : "" } } ) ;
294361 } ;
295362
0 commit comments