File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -56,4 +56,32 @@ describe("callChatbotApi", () => {
5656
5757 expect ( result ) . toBe ( fallback ) ;
5858 } ) ;
59+
60+ it ( "aborts when caller signal is aborted" , async ( ) => {
61+ const controller = new AbortController ( ) ;
62+ fetchMock . mockImplementationOnce (
63+ ( _url : string , init ?: RequestInit ) =>
64+ new Promise ( ( _ , reject ) => {
65+ const signal = init ?. signal as AbortSignal ;
66+ if ( signal ) {
67+ signal . addEventListener ( "abort" , ( ) => {
68+ reject ( new DOMException ( "Aborted" , "AbortError" ) ) ;
69+ } ) ;
70+ }
71+ } ) as Promise < Response > ,
72+ ) ;
73+
74+ const fallback = { error : "cancelled" } ;
75+ const promise = callChatbotApi (
76+ "cancel-endpoint" ,
77+ { signal : controller . signal } ,
78+ fallback ,
79+ 10000 ,
80+ ) ;
81+
82+ controller . abort ( ) ;
83+
84+ const result = await promise ;
85+ expect ( result ) . toEqual ( fallback ) ;
86+ } ) ;
5987} ) ;
Original file line number Diff line number Diff line change @@ -15,13 +15,16 @@ export const callChatbotApi = async <T>(
1515 fallbackErrorValue : T ,
1616 timeoutMs : number ,
1717) : Promise < T > => {
18- const controller = new AbortController ( ) ;
19- const id = setTimeout ( ( ) => controller . abort ( ) , timeoutMs ) ;
18+ const callerSignal = options . signal ;
19+ const timeoutSignal = AbortSignal . timeout ( timeoutMs ) ;
20+ const signal = callerSignal
21+ ? AbortSignal . any ( [ callerSignal , timeoutSignal ] )
22+ : timeoutSignal ;
2023
2124 try {
2225 const response = await fetch ( `${ API_BASE_URL } /api/chatbot/${ endpoint } ` , {
2326 ...options ,
24- signal : controller . signal ,
27+ signal,
2528 } ) ;
2629
2730 if ( ! response . ok ) {
@@ -31,15 +34,17 @@ export const callChatbotApi = async <T>(
3134
3235 return await response . json ( ) ;
3336 } catch ( error : unknown ) {
34- if ( error instanceof DOMException && error . name == "AbortError" ) {
35- console . error (
36- `API request to ${ endpoint } timed out after ${ timeoutMs } ms.` ,
37- ) ;
37+ if ( error instanceof DOMException && error . name === "AbortError" ) {
38+ if ( callerSignal ?. aborted ) {
39+ console . error ( "API request cancelled by user" ) ;
40+ } else {
41+ console . error (
42+ `API request to ${ endpoint } timed out after ${ timeoutMs } ms.` ,
43+ ) ;
44+ }
3845 } else {
3946 console . error ( `API error calling ${ endpoint } :` , error ) ;
4047 }
4148 return fallbackErrorValue ;
42- } finally {
43- clearTimeout ( id ) ;
4449 }
4550} ;
You can’t perform that action at this time.
0 commit comments