refactor(cli): standardize error handling and use packet.deinit()

- Replace std.process.exit(1) with error.InvalidArgs in sync command
- Replace std.process.exit(1) with error.ValidationFailed in validate command
- Update validate.zig to use protocol.ResponsePacket.deinit() for cleanup
- Build verified: zig build --release=fast
This commit is contained in:
Jeremie Fraeys 2026-02-18 13:29:53 -05:00
parent 9517271bbb
commit 29d130dcdb
No known key found for this signature in database
2 changed files with 10 additions and 35 deletions

View file

@ -2,6 +2,7 @@ const std = @import("std");
const testing = std.testing;
const Config = @import("../config.zig").Config;
const ws = @import("../net/ws/client.zig");
const protocol = @import("../net/protocol.zig");
const colors = @import("../utils/colors.zig");
const crypto = @import("../utils/crypto.zig");
const io = @import("../utils/io.zig");
@ -78,7 +79,7 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void {
const msg = try client.receiveMessage(allocator);
defer allocator.free(msg);
const packet = @import("../net/protocol.zig").ResponsePacket.deserialize(msg, allocator) catch {
const packet = protocol.ResponsePacket.deserialize(msg, allocator) catch {
if (opts.json) {
var out = io.stdoutWriter();
try out.print("{s}\n", .{msg});
@ -87,13 +88,7 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void {
}
return error.InvalidPacket;
};
defer {
if (packet.success_message) |m| allocator.free(m);
if (packet.error_message) |m| allocator.free(m);
if (packet.error_details) |m| allocator.free(m);
if (packet.data_type) |m| allocator.free(m);
if (packet.data_payload) |m| allocator.free(m);
}
defer packet.deinit(allocator);
if (packet.packet_type == .error_packet) {
try client.handleResponsePacket(packet, "validate");
@ -115,7 +110,7 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void {
const root = parsed.value.object;
const ok = try printHumanReport(root, opts.verbose);
if (!ok) std.process.exit(1);
if (!ok) return error.ValidationFailed;
}
}

View file

@ -22,77 +22,57 @@ pub fn main() !void {
const command = args[1];
// Track if we found a valid command
var command_found = false;
// Fast dispatch using switch on first character
switch (command[0]) {
'j' => if (std.mem.eql(u8, command, "jupyter")) {
command_found = true;
try @import("commands/jupyter.zig").run(allocator, args[2..]);
},
'i' => if (std.mem.eql(u8, command, "init")) {
command_found = true;
colors.printInfo("Setup configuration interactively\n", .{});
} else if (std.mem.eql(u8, command, "info")) {
command_found = true;
try @import("commands/info.zig").run(allocator, args[2..]);
},
'a' => if (std.mem.eql(u8, command, "annotate")) {
command_found = true;
try @import("commands/annotate.zig").run(allocator, args[2..]);
},
'n' => if (std.mem.eql(u8, command, "narrative")) {
command_found = true;
try @import("commands/narrative.zig").run(allocator, args[2..]);
},
's' => if (std.mem.eql(u8, command, "sync")) {
command_found = true;
if (args.len < 3) {
colors.printError("Usage: ml sync <path>\n", .{});
std.process.exit(1);
return error.InvalidArgs;
}
colors.printInfo("Sync project to server: {s}\n", .{args[2]});
} else if (std.mem.eql(u8, command, "status")) {
command_found = true;
try @import("commands/status.zig").run(allocator, args[2..]);
},
'r' => if (std.mem.eql(u8, command, "requeue")) {
command_found = true;
try @import("commands/requeue.zig").run(allocator, args[2..]);
},
'q' => if (std.mem.eql(u8, command, "queue")) {
command_found = true;
try @import("commands/queue.zig").run(allocator, args[2..]);
},
'd' => if (std.mem.eql(u8, command, "dataset")) {
command_found = true;
try @import("commands/dataset.zig").run(allocator, args[2..]);
},
'e' => if (std.mem.eql(u8, command, "experiment")) {
command_found = true;
try @import("commands/experiment.zig").execute(allocator, args[2..]);
},
'c' => if (std.mem.eql(u8, command, "cancel")) {
command_found = true;
try @import("commands/cancel.zig").run(allocator, args[2..]);
},
'v' => if (std.mem.eql(u8, command, "validate")) {
command_found = true;
try @import("commands/validate.zig").run(allocator, args[2..]);
},
'l' => if (std.mem.eql(u8, command, "logs")) {
command_found = true;
try @import("commands/logs.zig").run(allocator, args[2..]);
},
else => {},
}
// If no command was found, show error and exit
if (!command_found) {
colors.printError("Unknown command: {s}\n", .{args[1]});
printUsage();
std.process.exit(1);
else => {
colors.printError("Unknown command: {s}\n", .{args[1]});
printUsage();
return error.InvalidCommand;
},
}
}