I need errors to be logged in the same way across a large number of function calls. Here I want errors from foo.create(...) and File.new_tmp(...) to be logged by handle_error(...).
// compile with `valac --pkg gio-2.0 main.vala`
void log_error(Error e) {
// error logging here
}
void main() {
var foo = File.new_for_path("foo");
try {
foo.create(FileCreateFlags.NONE);
} catch (Error e) {
log_error(e);
}
FileIOStream tmp_stream;
try {
File.new_tmp(null, out tmp_stream);
} catch (Error e) {
log_error(e);
}
}
(Yes, main should continue with the FileIOStream stuff if foo.create fails, which is why they're in separate try/catch blocks.)
I want to factor out the use of try {...} catch (Error e) {log_error(e);} into a function like so:
delegate void Action();
void log_error(global::Action action) {
try {
action();
} catch (Error e) {
// error logging here
}
}
void main() {
var foo = File.new_for_path("foo");
log_error(() => foo.create(FileCreateFlags.NONE));
FileIOStream tmp_stream;
log_error(() => File.new_tmp(null, out tmp_stream));
}
But valac gives the warning unhandled error 'GLib.IOError' because you can't seem to catch errors thrown within a closure, nor can I just rewrite log_error(...) as a #define macro as vala doesn't support them. So what can I do?
You can catch exceptions thrown in closures, you just need to have the delegate throw the exception. What you want is probably something like this:
public delegate T? Action<T> () throws GLib.Error;
T? log_error<T> (global::Action<T> func) {
try {
return func ();
} catch (GLib.Error e) {
// error logging here
return null;
}
}
void main () {
var foo = File.new_for_path("foo");
log_error<GLib.FileOutputStream> (() => foo.create (FileCreateFlags.NONE));
FileIOStream? tmp_stream = null;
GLib.File? f = log_error<GLib.File> (() => File.new_tmp (null, out tmp_stream));
}
Note that I've made it a generic so you can actually use a return value. If you want it should be trivial to remove the generic type argument and just return void, though you'll lose some flexivility.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With