向异常添加额外信息

时间:2010-10-22 07:03:05

标签: language-agnostic exception-handling

假设我有从csv文件中读取客户的方法。

读取文件时会发生异常(例如IOException或FormatException)。在大多数情况下,该方法无法对错误做任何事情,但它可以添加额外的信息,如文件名,行号等。

该方法的类有一个IProgressAndErrorReporter依赖项,用于记录/显示错误。

如何向来电者报告发生错误但已经处理错误?

目前我这样做:

class CustomerReader
{
    private readonly IProgressAndErrorReporter mProgressAndErrorReporter;

    public bool TryReadCustomers() {
        try {
            ...
            return true;
        }
        catch (IOException err) {
            mProgressAndErrorReporter.ReportError(err, "Can't read file {0} bla bla");
            return false;
         }
    }
 }

(我只捕获“预期的”例外,即不是InvalidOperation等) 我的工作正常,但在数据处理应用程序的类型中,我通常使用上面的级别看起来像:

public bool TryProcessData() {
    if (!customerReader.TryReadCustomers())
        return false;

    var orders = webOrderReader.ReadNewOrders());
    if (orders == null)
        return false;

    if (!orderCreator.TryCreateNewOrder(order))
    ...

}

对我而言,感觉就像是回到了例外之前的时间。

我应该在顶层使用一个空的catch子句抛出某种“AlreadyHandledException”吗?

1 个答案:

答案 0 :(得分:1)

不要回到过去,而是将它包装在更高级别的异常中。在这种情况下,您应该定义ReadCustormerDataException和ReadNewOrderException。这具有创建非常易读的代码的额外好处。创建一个新的异常并不难,如果你的语言有内部类,你可以创建一个公共内部类。

最后,如果你应该返回一个布尔值,它取决于用例,但是我建议你在更高级别的方法中捕获自定义(已检查)异常,实际上需要布尔值,而不是之前。

如果您的方法在正常条件下绑定失败,则不抛出异常但返回(自定义)结果类。这将确保您和您的同事不必确保调试器在正常操作中停止在您的代码中。最后,如果您有许多不应该停止应用程序的异常,您可能希望将结果类传递给侦听器,而不是在方法结束时返回它。

如果你确定信息存在,PS只包含额外的信息(否则你最终会在异常处理中产生异常) - 不好(错误,找不到错误表是我的最爱)。