error-handling - 如何分解我对 `try {...} catch (Error e) {log_error(e);}` 的使用

标签 error-handling closures vala

我需要在大量函数调用中以相同的方式记录错误。在这里,我希望由 handle_error(...)< 记录来自 foo.create(...)File.new_tmp(...) 的错误.

// 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);
    }
}

(是的,如果 foo.create 失败,main 应该继续使用 FileIOStream 内容,这就是为什么它们在单独的 try/catch block 。)

我想将 try {...} catch (Error e) {log_error(e);} 的使用分解为如下函数:

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));
}

但是 valac 给出了警告 unhandled error 'GLib.IOError' 因为你似乎无法捕获闭包中抛出的错误,我也不能重写 log_error(...) 作为 #define 宏,因为 vala 不支持它们。那我能做什么呢?

最佳答案

你可以捕获闭包中抛出的异常,你只需要让委托(delegate)抛出异常即可。你想要的可能是这样的:

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));
}

请注意,我已将其设为泛型,因此您实际上可以使用返回值。如果您愿意,删除泛型类型参数并返回 void 应该很简单,但您会失去一些灵活性。

关于error-handling - 如何分解我对 `try {...} catch (Error e) {log_error(e);}` 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24349403/

相关文章:

segmentation-fault - 使用 Vala 自定义 GTK 小部件

.net - 在 C++/CLI 包装类中转换异常的最佳实践

ios - swift中错误和异常的区别

javascript - 如何在闭包中使用 'uncapture' 变量?

asynchronous - 如何在 Rust 中返回一个返回特征的函数

gtk - 瓦拉 Gtk 模板 : UI Resource not found

actionscript-3 - 将所有错误定向到文本字段

angular - Angular 2错误永远不会进入自定义错误处理程序

swift - 为什么我必须解开一个软弱的 self ?

vala - 需要 vala 中的 setter/getter