milestone 19: hygiene sweep - dead ecs surface, single-source constants, tls classification, frontend state hazards, docker smoke network fix
CI / test (push) Successful in 1m46s
CI / test-aarch64 (push) Successful in 5m30s
CI / frontend (push) Successful in 46s
CI / cross (push) Successful in 8m12s
CI / docker (push) Successful in 3m46s

This commit is contained in:
2026-08-07 20:39:27 +02:00
parent 6f67940995
commit 6c507992e4
59 changed files with 1020 additions and 382 deletions
+33 -6
View File
@@ -156,6 +156,32 @@ fn parseUrl(url: []const u8) Error!std.Uri {
/// first time two phases shared an error.
const Phase = enum { connect, send, receive };
// `error.X` in an expression names a member into existence rather than
// referring to one, so the switch in `mapError` would keep compiling — and
// silently stop matching — if std renamed either of these. This is what fails
// the build instead.
comptime {
for ([_][]const u8{ "TlsInitializationFailed", "CertificateBundleLoadFailure" }) |name| {
if (!errorSetHas(std.http.Client.RequestError, name)) {
@compileError("std.http.Client.RequestError no longer names " ++ name);
}
}
}
fn errorSetHas(comptime Set: type, comptime name: []const u8) bool {
for (@typeInfo(Set).error_set.?) |member| {
if (std.mem.eql(u8, member.name, name)) return true;
}
return false;
}
/// The two names are the whole TLS surface this file can reach.
/// `std.http.Client` collapses every handshake fault into
/// `error.TlsInitializationFailed` (Client.zig:1470) and every bundle fault into
/// `error.CertificateBundleLoadFailure`, and this file never unwraps a
/// connection's stashed read cause — it maps the collapsed `error.ReadFailed` by
/// phase — so the record-layer members of `std.crypto.tls.Client.ReadError`
/// cannot arrive here. `doh_client.zig` does unwrap, and names them.
fn mapError(err: anyerror, phase: Phase) Error {
if (transport.mapLocal(err)) |local| return narrowLocal(local);
switch (err) {
@@ -165,9 +191,10 @@ fn mapError(err: anyerror, phase: Phase) Error {
error.TooManyHttpRedirects => return error.HttpStatus,
else => {},
}
const err_name = @errorName(err);
if (std.mem.startsWith(u8, err_name, "Tls") or
std.mem.startsWith(u8, err_name, "Certificate")) return error.TlsFailed;
switch (err) {
error.TlsInitializationFailed, error.CertificateBundleLoadFailure => return error.TlsFailed,
else => {},
}
return switch (phase) {
.connect => error.ConnectFailed,
.send => error.SendFailed,
@@ -307,10 +334,10 @@ test "mapError maps local errors before phase errors" {
);
}
test "mapError maps tls errors regardless of phase" {
test "mapError maps the reachable tls errors regardless of phase" {
try testing.expectEqual(error.TlsFailed, mapError(error.TlsInitializationFailed, .connect));
try testing.expectEqual(error.TlsFailed, mapError(error.TlsAlert, .receive));
try testing.expectEqual(error.TlsFailed, mapError(error.CertificateExpired, .connect));
try testing.expectEqual(error.TlsFailed, mapError(error.TlsInitializationFailed, .receive));
try testing.expectEqual(error.TlsFailed, mapError(error.CertificateBundleLoadFailure, .connect));
}
test "mapError maps a redirect overrun to HttpStatus" {