From 3bb2f7b84ed8b1ee09b6077f66e28ab7291a7bd4 Mon Sep 17 00:00:00 2001 From: Matthew Lugg Date: Wed, 31 Dec 2025 13:11:05 +0000 Subject: [PATCH] std.Io.net: don't swallow 'error.Canceled' This was missed when updating to the new group cancelation API, and caused illegal behavior in many cases (the condition was simply that a DNS query returned a second result before a connection was successfully established). --- lib/std/Io/net/HostName.zig | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/std/Io/net/HostName.zig b/lib/std/Io/net/HostName.zig index 03f92cc022..8ae02ef825 100644 --- a/lib/std/Io/net/HostName.zig +++ b/lib/std/Io/net/HostName.zig @@ -233,11 +233,12 @@ pub fn connect( if (result) |stream| { return stream; } else |err| switch (err) { + error.Canceled => unreachable, + error.SystemResources, error.OptionUnsupported, error.ProcessFdQuotaExceeded, error.SystemFdQuotaExceeded, - error.Canceled, => |e| return e, error.WouldBlock => return error.Unexpected, @@ -259,6 +260,8 @@ pub fn connect( /// Asynchronously establishes a connection to all IP addresses associated with /// a host name, adding them to a results queue upon completion. /// +/// `error.Canceled` will never be added to the queue, but other errors may be. +/// /// Closes `results` before return, even on error. /// /// Asserts `results` is not closed until this call returns. @@ -299,22 +302,15 @@ fn enqueueConnection( io: Io, queue: *Io.Queue(IpAddress.ConnectError!Stream), options: IpAddress.ConnectOptions, -) void { - enqueueConnectionFallible(address, io, queue, options) catch |err| switch (err) { - error.Canceled => {}, - }; -} -fn enqueueConnectionFallible( - address: IpAddress, - io: Io, - queue: *Io.Queue(IpAddress.ConnectError!Stream), - options: IpAddress.ConnectOptions, ) Io.Cancelable!void { - const result = address.connect(io, options); + const result = address.connect(io, options) catch |err| switch (err) { + error.Canceled => |e| return e, + else => |e| e, // other errors go in the result queue + }; errdefer if (result) |s| s.close(io) else |_| {}; queue.putOne(io, result) catch |err| switch (err) { - error.Closed => unreachable, // `queue` must not be closed error.Canceled => |e| return e, + error.Closed => unreachable, // `queue` must not be closed }; }