@@ -354,6 +354,7 @@ pub const Request = struct {
354354 // Because of things like redirects and error handling, it is possible for
355355 // the notification functions to be called multiple times, so we guard them
356356 // with these booleans
357+ _notified_fail : bool ,
357358 _notified_start : bool ,
358359 _notified_complete : bool ,
359360
@@ -414,6 +415,7 @@ pub const Request = struct {
414415 ._keepalive = false ,
415416 ._redirect_count = 0 ,
416417 ._has_host_header = false ,
418+ ._notified_fail = false ,
417419 ._notified_start = false ,
418420 ._notified_complete = false ,
419421 ._connection_from_keepalive = false ,
@@ -428,6 +430,7 @@ pub const Request = struct {
428430 }
429431
430432 pub fn abort (self : * Request ) void {
433+ self .requestFailed ("aborted" );
431434 const aborter = self ._aborter orelse {
432435 self .deinit ();
433436 return ;
@@ -555,6 +558,10 @@ pub const Request = struct {
555558 }
556559
557560 fn doSendSync (self : * Request , use_pool : bool ) anyerror ! Response {
561+ // https://github.com/ziglang/zig/issues/20369
562+ // errdefer |err| self.requestFailed(@errorName(err));
563+ errdefer self .requestFailed ("network error" );
564+
558565 if (use_pool ) {
559566 if (self .findExistingConnection (true )) | connection | {
560567 self ._connection = connection ;
@@ -847,6 +854,19 @@ pub const Request = struct {
847854 });
848855 }
849856
857+ fn requestFailed (self : * Request , err : []const u8 ) void {
858+ const notification = self .notification orelse return ;
859+ if (self ._notified_fail ) {
860+ return ;
861+ }
862+ self ._notified_fail = true ;
863+ notification .dispatch (.http_request_fail , &.{
864+ .id = self .id ,
865+ .err = err ,
866+ .url = self .request_uri ,
867+ });
868+ }
869+
850870 fn requestCompleted (self : * Request , response : ResponseHeader ) void {
851871 const notification = self .notification orelse return ;
852872 if (self ._notified_complete ) {
@@ -1290,6 +1310,8 @@ fn AsyncHandler(comptime H: type, comptime L: type) type {
12901310 self .handler .onHttpResponse (err ) catch {};
12911311 // just to be safe
12921312 self .request ._keepalive = false ;
1313+
1314+ self .request .requestFailed (@errorName (err ));
12931315 self .request .deinit ();
12941316 }
12951317
0 commit comments