11import { txToast , validToastTypes } from "@/components/TxToaster" ;
22import { useCsrfToken , useExpireAuthData } from "@/hooks/auth" ;
3+ import { msToShortDuration } from "@/lib/dateTime" ;
34import { useEffect , useRef } from "react" ;
45
56const WEBPIPE_PATH = "https://monitor/WebPipe" ;
@@ -131,6 +132,9 @@ type ApiCallOpts<RespType, ReqType> = {
131132 finally ?: ( ) => void ;
132133}
133134
135+ //Just syntax sugar
136+ const VOID = undefined as void ;
137+
134138export const useBackendApi = <
135139 RespType = any ,
136140 ReqType = NonNullable < Object > ,
@@ -149,6 +153,9 @@ export const useBackendApi = <
149153 }
150154 } , [ ] ) ;
151155
156+ /**
157+ * @returns VOID if the request was aborted or error was handled, otherwise the response data
158+ */
152159 return async ( opts : ApiCallOpts < RespType , ReqType > ) => {
153160 //The abort controller is not aborted, just forgotten
154161 abortController . current = new AbortController ( ) ;
@@ -205,12 +212,14 @@ export const useBackendApi = <
205212 }
206213
207214 //Starting request timeout
215+ const timeoutMs = opts . timeout ?? ApiTimeout . DEFAULT ;
208216 const timeoutId = setTimeout ( ( ) => {
209217 if ( abortController . current ?. signal . aborted ) return ;
210218 console . log ( '[TIMEOUT]' , apiCallDesc ) ;
211- abortController . current ?. abort ( 'timeout' ) ;
219+ const msg = `Request timed out after ${ msToShortDuration ( timeoutMs , { units : [ 's' , 'ms' ] } ) } .` ;
220+ abortController . current ?. abort ( msg ) ;
212221 handleError ( 'Request Timeout' , 'If you closed txAdmin, please restart it and try again.' ) ;
213- } , opts . timeout ?? ApiTimeout . DEFAULT ) ;
222+ } , timeoutMs ) ;
214223
215224 try {
216225 //Make request
@@ -220,7 +229,9 @@ export const useBackendApi = <
220229 body : opts . data ,
221230 } , abortController . current ) ;
222231 clearTimeout ( timeoutId ) ;
223- if ( abortController . current ?. signal . aborted ) return ;
232+ // if (abortController.current?.signal.aborted) {
233+ // throw abortController.current.signal.reason;
234+ // };
224235
225236 //If generic error
226237 if ( hookOpts . throwGenericErrors && 'error' in data ) {
@@ -261,11 +272,22 @@ export const useBackendApi = <
261272 return data as RespType ;
262273
263274 } catch ( e ) {
264- if ( abortController . current ?. signal . aborted ) return ;
275+ // console.warn('Error Handling:', {
276+ // aborted: abortController.current?.signal.aborted,
277+ // reason: abortController.current?.signal.reason,
278+ // typeof: typeof e,
279+ // e,
280+ // });
265281 clearTimeout ( timeoutId ) ;
282+ if ( e === 'unmount' ) {
283+ console . warn ( '[UNMOUNTED]' , apiCallDesc ) ;
284+ return VOID ;
285+ }
286+ const error = abortController . current ?. signal . reason ?? e as any ;
266287 let errorMessage = 'unknown error' ;
267- const error = e as any ;
268- if ( typeof error . message !== 'string' ) {
288+ if ( typeof error === 'string' ) {
289+ errorMessage = error ;
290+ } else if ( typeof error . message !== 'string' ) {
269291 errorMessage = JSON . stringify ( error ) ;
270292 } else if ( error . message . startsWith ( 'NetworkError' ) ) {
271293 errorMessage = 'Network error.\nIf you closed txAdmin, please restart it and try again.' ;
@@ -274,13 +296,10 @@ export const useBackendApi = <
274296 } else {
275297 errorMessage = error . message ;
276298 }
277-
278- if ( errorMessage . includes ( 'unmount' ) ) {
279- console . warn ( '[UNMOUNTED]' , apiCallDesc ) ;
280- } else {
281- console . error ( '[ERROR]' , apiCallDesc , errorMessage ) ;
282- handleError ( 'Request Error' , errorMessage ) ;
283- }
299+
300+ console . error ( '[ERROR]' , apiCallDesc , errorMessage ) ;
301+ handleError ( 'Request Error' , errorMessage ) ;
302+ return VOID ;
284303 } finally {
285304 if ( opts . finally ) {
286305 try {
0 commit comments