Commit 8d86194b6e

Nameless <truemedian@gmail.com>
2023-03-07 03:11:56
add error sets to tcpConnect* and tls.Client.init
1 parent afb26f4
Changed files (2)
lib
std
lib/std/crypto/tls/Client.zig
@@ -88,11 +88,59 @@ pub const StreamInterface = struct {
     }
 };
 
+pub fn InitError(comptime Stream: type) type {
+    return std.mem.Allocator.Error || Stream.WriteError || Stream.ReadError || error {
+        InsufficientEntropy,
+        DiskQuota,
+        LockViolation,
+        NotOpenForWriting,
+        TlsAlert,
+        TlsUnexpectedMessage,
+        TlsIllegalParameter,
+        TlsDecryptFailure,
+        TlsRecordOverflow,
+        TlsBadRecordMac,
+        CertificateFieldHasInvalidLength,
+        CertificateHostMismatch,
+        CertificatePublicKeyInvalid,
+        CertificateExpired,
+        CertificateFieldHasWrongDataType,
+        CertificateIssuerMismatch,
+        CertificateNotYetValid,
+        CertificateSignatureAlgorithmMismatch,
+        CertificateSignatureAlgorithmUnsupported,
+        CertificateSignatureInvalid,
+        CertificateSignatureInvalidLength,
+        CertificateSignatureNamedCurveUnsupported,
+        CertificateSignatureUnsupportedBitCount,
+        TlsCertificateNotVerified,
+        TlsBadSignatureScheme,
+        TlsBadRsaSignatureBitCount,
+        InvalidEncoding,
+        IdentityElement,
+        SignatureVerificationFailed,
+        TlsDecryptError,
+        TlsConnectionTruncated,
+        TlsDecodeError,
+        UnsupportedCertificateVersion,
+        CertificateTimeInvalid,
+        CertificateHasUnrecognizedObjectId,
+        CertificateHasInvalidBitString,
+        MessageTooLong,
+        NegativeIntoUnsigned,
+        TargetTooSmall,
+        BufferTooSmall,
+        InvalidSignature,
+        NotSquare,
+        NonCanonical,
+    };
+}
+
 /// Initiates a TLS handshake and establishes a TLSv1.3 session with `stream`, which
 /// must conform to `StreamInterface`.
 ///
 /// `host` is only borrowed during this function call.
-pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) !Client {
+pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) InitError(@TypeOf(stream))!Client {
     const host_len = @intCast(u16, host.len);
 
     var random_buffer: [128]u8 = undefined;
lib/std/net.zig
@@ -702,8 +702,10 @@ pub const AddressList = struct {
     }
 };
 
+pub const TcpConnectToHostError = GetAddressListError || TcpConnectToAddressError;
+
 /// All memory allocated with `allocator` will be freed before this function returns.
-pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) !Stream {
+pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) TcpConnectToHostError!Stream {
     const list = try getAddressList(allocator, name, port);
     defer list.deinit();
 
@@ -720,7 +722,9 @@ pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) !
     return std.os.ConnectError.ConnectionRefused;
 }
 
-pub fn tcpConnectToAddress(address: Address) !Stream {
+pub const TcpConnectToAddressError = std.os.SocketError || std.os.ConnectError;
+
+pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream {
     const nonblock = if (std.io.is_async) os.SOCK.NONBLOCK else 0;
     const sock_flags = os.SOCK.STREAM | nonblock |
         (if (builtin.target.os.tag == .windows) 0 else os.SOCK.CLOEXEC);
@@ -737,8 +741,32 @@ pub fn tcpConnectToAddress(address: Address) !Stream {
     return Stream{ .handle = sockfd };
 }
 
+const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || error {
+    // TODO: break this up into error sets from the various underlying functions
+    
+    TemporaryNameServerFailure,
+    NameServerFailure,
+    AddressFamilyNotSupported,
+    UnknownHostName,
+    ServiceUnavailable,
+    Unexpected,
+
+    HostLacksNetworkAddresses,
+
+    InvalidCharacter,
+    InvalidEnd,
+    NonCanonical,
+    Overflow,
+    Incomplete,
+    InvalidIpv4Mapping,
+    InvalidIPAddressFormat,
+    
+    InterfaceNotFound,
+    FileSystem,
+};
+
 /// Call `AddressList.deinit` on the result.
-pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*AddressList {
+pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) GetAddressListError!*AddressList {
     const result = blk: {
         var arena = std.heap.ArenaAllocator.init(allocator);
         errdefer arena.deinit();