@@ -247,8 +247,47 @@ class QUICClient {
247247 // the client, because the client bridges the push flow from the connection
248248 // to the socket.
249249 socket . connectionMap . set ( connection . connectionId , connection ) ;
250+ // Set up intermediate abort signal
251+ const abortController = new AbortController ( ) ;
252+ const abortHandler = ( ) => {
253+ abortController . abort ( ctx . signal . reason ) ;
254+ } ;
255+ if ( ctx . signal . aborted ) abortController . abort ( ctx . signal . reason ) ;
256+ else ctx . signal . addEventListener ( 'abort' , abortHandler ) ;
257+ const handleEventQUICClientErrorSend = (
258+ evt : events . EventQUICClientErrorSend ,
259+ ) => {
260+ // @ts -ignore: the error contains `code` but not part of the type
261+ const code = evt . detail . code ;
262+ switch ( code ) {
263+ // Thrown due to invalid arguments on linux
264+ case 'EINVAL' :
265+ // Thrown due to invalid arguments on macOS
266+ // Falls through
267+ case 'EADDRNOTAVAIL' :
268+ // Thrown due to invalid arguments on Win but also for network dropouts on all platforms
269+ // Falls through
270+ case 'ENETUNREACH' :
271+ {
272+ abortController . abort (
273+ new errors . ErrorQUICClientInvalidArgument ( undefined , {
274+ cause : evt . detail ,
275+ } ) ,
276+ ) ;
277+ }
278+ break ;
279+ default : // Do nothing
280+ }
281+ } ;
282+ client . addEventListener (
283+ `${ events . EventQUICClientErrorSend . name } -${ connection . sendId } ` ,
284+ handleEventQUICClientErrorSend ,
285+ ) ;
250286 try {
251- await connection . start ( undefined , ctx ) ;
287+ await connection . start ( undefined , {
288+ timer : ctx . timer ,
289+ signal : abortController . signal ,
290+ } ) ;
252291 } catch ( e ) {
253292 socket . connectionMap . delete ( connection . connectionId ) ;
254293 socket . removeEventListener (
@@ -284,6 +323,12 @@ class QUICClient {
284323 client . handleEventQUICClientClose ,
285324 ) ;
286325 throw e ;
326+ } finally {
327+ ctx . signal . removeEventListener ( 'abort' , abortHandler ) ;
328+ client . removeEventListener (
329+ `${ events . EventQUICClientErrorSend . name } -${ connection . sendId } ` ,
330+ handleEventQUICClientErrorSend ,
331+ ) ;
287332 }
288333 address = utils . buildAddress ( host_ , port ) ;
289334 logger . info ( `Created ${ this . name } to ${ address } ` ) ;
@@ -459,14 +504,42 @@ class QUICClient {
459504 evt . detail . address ,
460505 ) ;
461506 } catch ( e ) {
462- const e_ = new errors . ErrorQUICClientInternal (
463- 'Failed to send data on the QUICSocket' ,
464- {
465- data : evt . detail ,
466- cause : e ,
467- } ,
468- ) ;
469- this . dispatchEvent ( new events . EventQUICClientError ( { detail : e_ } ) ) ;
507+ switch ( e . code ) {
508+ // Thrown due to invalid arguments on linux
509+ case 'EINVAL' :
510+ // Thrown due to invalid arguments on macOS
511+ // Falls through
512+ case 'EADDRNOTAVAIL' :
513+ // Thrown due to invalid arguments on Win but also for network dropouts on all platforms
514+ // Falls through
515+ case 'ENETUNREACH' :
516+ {
517+ this . dispatchEvent (
518+ new events . EventQUICClientErrorSend (
519+ `${ events . EventQUICClientErrorSend . name } -${ evt . detail . id } ` ,
520+ {
521+ detail : e ,
522+ } ,
523+ ) ,
524+ ) ;
525+ }
526+ break ;
527+ default :
528+ {
529+ this . dispatchEvent (
530+ new events . EventQUICClientError ( {
531+ detail : new errors . ErrorQUICClientInternal (
532+ 'Failed to send data on the QUICSocket' ,
533+ {
534+ data : evt . detail ,
535+ cause : e ,
536+ } ,
537+ ) ,
538+ } ) ,
539+ ) ;
540+ }
541+ break ;
542+ }
470543 }
471544 } ;
472545
0 commit comments