improve more error messages
This commit is contained in:
80
src/main.zig
80
src/main.zig
@@ -1,6 +1,7 @@
|
||||
const std = @import("std");
|
||||
const info = std.log.info;
|
||||
const debug = std.log.debug;
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
const print = std.debug.print;
|
||||
const eql = std.mem.eql;
|
||||
const Allocator = std.mem.Allocator;
|
||||
@@ -21,7 +22,9 @@ pub fn main() !void {
|
||||
},
|
||||
ArgumentError.UnknownParameter, //
|
||||
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)
|
||||
},
|
||||
@@ -167,7 +170,7 @@ fn zeroPad(allocator: Allocator, digits: u4, x: anytype) ![]u8 {
|
||||
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 {
|
||||
var result = Args{
|
||||
@@ -274,34 +277,65 @@ fn configLocation(allocator: Allocator) ![]const u8 {
|
||||
/// Reads the config file into a list of OtpAuthUrl.
|
||||
/// The caller should use an arena allocator and free the memory eventually.
|
||||
fn read_config(allocator: Allocator, config_location: []const u8) !ArrayList(OtpAuthUrl) {
|
||||
const file = try std.fs.cwd().openFile(config_location, .{});
|
||||
defer file.close();
|
||||
const file_result = std.fs.cwd().openFile(config_location, .{});
|
||||
if (file_result) |file| {
|
||||
defer file.close();
|
||||
|
||||
var buf_reader = std.io.bufferedReader(file.reader());
|
||||
var in_stream = buf_reader.reader();
|
||||
var buf_reader = std.io.bufferedReader(file.reader());
|
||||
var in_stream = buf_reader.reader();
|
||||
|
||||
var authenticators = std.ArrayList(OtpAuthUrl).init(allocator);
|
||||
var authenticators = std.ArrayList(OtpAuthUrl).init(allocator);
|
||||
|
||||
var line_no: usize = 1;
|
||||
while (try in_stream.readUntilDelimiterOrEofAlloc(allocator, '\n', 1024 * 1024)) |line| {
|
||||
if (line.len > 0 and std.mem.trim(u8, line, " \r").len > 0) {
|
||||
const authenticatorResult = parseOtpAuthUrl(allocator, line);
|
||||
if (authenticatorResult) |authenticator| {
|
||||
try authenticators.append(authenticator);
|
||||
} else |err| {
|
||||
switch (err) {
|
||||
error.InvalidOtpAuthUrl => {
|
||||
try std.io.getStdErr().writer().print("invalid otpauth url in line {d} in {s}\n", .{ line_no, config_location });
|
||||
},
|
||||
else => {
|
||||
return err;
|
||||
},
|
||||
var number_of_errors: u32 = 0;
|
||||
var line_no: usize = 1;
|
||||
while (try in_stream.readUntilDelimiterOrEofAlloc(allocator, '\n', 1024 * 1024)) |line| {
|
||||
if (line.len > 0 and std.mem.trim(u8, line, " \r").len > 0) {
|
||||
const authenticatorResult = parseOtpAuthUrl(allocator, line);
|
||||
if (authenticatorResult) |authenticator| {
|
||||
try authenticators.append(authenticator);
|
||||
} else |err| {
|
||||
number_of_errors += 1;
|
||||
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 => {
|
||||
try std.io.getStdErr().writer().print("invalid otpauth url in line {d} in {s}\n", .{ line_no, config_location });
|
||||
},
|
||||
else => {
|
||||
return err;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
line_no += 1;
|
||||
}
|
||||
line_no += 1;
|
||||
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;
|
||||
}
|
||||
return authenticators;
|
||||
}
|
||||
|
||||
fn executeGetList(allocator: Allocator, config_location: []const u8) !std.ArrayList([]const u8) {
|
||||
|
||||
Reference in New Issue
Block a user