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 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,34 +277,65 @@ 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, .{});
|
||||||
defer file.close();
|
if (file_result) |file| {
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
var buf_reader = std.io.bufferedReader(file.reader());
|
var buf_reader = std.io.bufferedReader(file.reader());
|
||||||
var in_stream = buf_reader.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;
|
var number_of_errors: u32 = 0;
|
||||||
while (try in_stream.readUntilDelimiterOrEofAlloc(allocator, '\n', 1024 * 1024)) |line| {
|
var line_no: usize = 1;
|
||||||
if (line.len > 0 and std.mem.trim(u8, line, " \r").len > 0) {
|
while (try in_stream.readUntilDelimiterOrEofAlloc(allocator, '\n', 1024 * 1024)) |line| {
|
||||||
const authenticatorResult = parseOtpAuthUrl(allocator, line);
|
if (line.len > 0 and std.mem.trim(u8, line, " \r").len > 0) {
|
||||||
if (authenticatorResult) |authenticator| {
|
const authenticatorResult = parseOtpAuthUrl(allocator, line);
|
||||||
try authenticators.append(authenticator);
|
if (authenticatorResult) |authenticator| {
|
||||||
} else |err| {
|
try authenticators.append(authenticator);
|
||||||
switch (err) {
|
} else |err| {
|
||||||
error.InvalidOtpAuthUrl => {
|
number_of_errors += 1;
|
||||||
try std.io.getStdErr().writer().print("invalid otpauth url in line {d} in {s}\n", .{ line_no, config_location });
|
switch (err) {
|
||||||
},
|
error.UnexpectedCharacter, error.InvalidFormat => {
|
||||||
else => {
|
try stderr.print("Unexpected character in line {d} in file {s}. Line will be ignored.\n", .{ line_no, config_location });
|
||||||
return err;
|
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) {
|
fn executeGetList(allocator: Allocator, config_location: []const u8) !std.ArrayList([]const u8) {
|
||||||
|
|||||||
Reference in New Issue
Block a user