improve more error messages

This commit is contained in:
2024-09-11 13:45:24 +02:00
parent 1efad3d45c
commit 51def513e3

View File

@@ -1,6 +1,7 @@
const std = @import("std"); const std = @import("std");
const info = std.log.info; const info = std.log.info;
const debug = std.log.debug; const debug = std.log.debug;
const stderr = std.io.getStdErr().writer();
const print = std.debug.print; const print = std.debug.print;
const eql = std.mem.eql; const eql = std.mem.eql;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
@@ -21,7 +22,9 @@ pub fn main() !void {
}, },
ArgumentError.UnknownParameter, // ArgumentError.UnknownParameter, //
ArgumentError.MissingAuthenticatorParam, // ArgumentError.MissingAuthenticatorParam, //
ArgumentError.MissingConfigLocation, ArgumentError.MissingConfigLocation, //
ArgumentError.FailedToOpenConfigFile, //
ArgumentError.TooManyParsinErrors, //
=> { => {
// do nothing, error message is already written (because the message contains the name of the unknown parameter) // do nothing, error message is already written (because the message contains the name of the unknown parameter)
}, },
@@ -167,7 +170,7 @@ fn zeroPad(allocator: Allocator, digits: u4, x: anytype) ![]u8 {
return result; return result;
} }
const ArgumentError = error{ InvalidOtpAuthUrl, UnknownParameter, MissingConfigLocation, AuthenticatorNotFound, MissingAuthenticatorParam }; const ArgumentError = error{ InvalidOtpAuthUrl, UnknownParameter, MissingConfigLocation, AuthenticatorNotFound, MissingAuthenticatorParam, FailedToOpenConfigFile, TooManyParsinErrors };
fn parseArgs(allocator: Allocator, args: []const []const u8) !Args { fn parseArgs(allocator: Allocator, args: []const []const u8) !Args {
var result = Args{ var result = Args{
@@ -274,7 +277,8 @@ fn configLocation(allocator: Allocator) ![]const u8 {
/// Reads the config file into a list of OtpAuthUrl. /// Reads the config file into a list of OtpAuthUrl.
/// The caller should use an arena allocator and free the memory eventually. /// The caller should use an arena allocator and free the memory eventually.
fn read_config(allocator: Allocator, config_location: []const u8) !ArrayList(OtpAuthUrl) { fn read_config(allocator: Allocator, config_location: []const u8) !ArrayList(OtpAuthUrl) {
const file = try std.fs.cwd().openFile(config_location, .{}); const file_result = std.fs.cwd().openFile(config_location, .{});
if (file_result) |file| {
defer file.close(); defer file.close();
var buf_reader = std.io.bufferedReader(file.reader()); var buf_reader = std.io.bufferedReader(file.reader());
@@ -282,6 +286,7 @@ fn read_config(allocator: Allocator, config_location: []const u8) !ArrayList(Otp
var authenticators = std.ArrayList(OtpAuthUrl).init(allocator); var authenticators = std.ArrayList(OtpAuthUrl).init(allocator);
var number_of_errors: u32 = 0;
var line_no: usize = 1; var line_no: usize = 1;
while (try in_stream.readUntilDelimiterOrEofAlloc(allocator, '\n', 1024 * 1024)) |line| { while (try in_stream.readUntilDelimiterOrEofAlloc(allocator, '\n', 1024 * 1024)) |line| {
if (line.len > 0 and std.mem.trim(u8, line, " \r").len > 0) { if (line.len > 0 and std.mem.trim(u8, line, " \r").len > 0) {
@@ -289,7 +294,15 @@ fn read_config(allocator: Allocator, config_location: []const u8) !ArrayList(Otp
if (authenticatorResult) |authenticator| { if (authenticatorResult) |authenticator| {
try authenticators.append(authenticator); try authenticators.append(authenticator);
} else |err| { } else |err| {
number_of_errors += 1;
switch (err) { switch (err) {
error.UnexpectedCharacter, error.InvalidFormat => {
try stderr.print("Unexpected character in line {d} in file {s}. Line will be ignored.\n", .{ line_no, config_location });
if (number_of_errors >= 10) {
try stderr.print("too many parsing errors\n", .{});
return ArgumentError.TooManyParsinErrors;
}
},
error.InvalidOtpAuthUrl => { error.InvalidOtpAuthUrl => {
try std.io.getStdErr().writer().print("invalid otpauth url in line {d} in {s}\n", .{ line_no, config_location }); try std.io.getStdErr().writer().print("invalid otpauth url in line {d} in {s}\n", .{ line_no, config_location });
}, },
@@ -302,6 +315,27 @@ fn read_config(allocator: Allocator, config_location: []const u8) !ArrayList(Otp
line_no += 1; line_no += 1;
} }
return authenticators; return authenticators;
} else |err| {
//debug("file open error: {}\n", .{err});
switch (err) {
error.AccessDenied, //
error.BadPathName,
error.InvalidWtf8,
=> {
try stderr.print("cannot open config file: {}\n", .{err});
},
error.FileNotFound => {
try stderr.print("config file not found. Create a new config file in $HOME/.zig-totp or $XDG_CONFIG_HOME/zig-totp.\n", .{});
},
error.IsDir => {
try stderr.print("the configuration location must be a file, but is a directory.\n", .{});
},
else => {
return err;
},
}
return ArgumentError.FailedToOpenConfigFile;
}
} }
fn executeGetList(allocator: Allocator, config_location: []const u8) !std.ArrayList([]const u8) { fn executeGetList(allocator: Allocator, config_location: []const u8) !std.ArrayList([]const u8) {