代码之家  ›  专栏  ›  技术社区  ›  adrianm

向异常添加额外信息

  •  0
  • adrianm  · 技术社区  · 14 年前

    假设我有从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;
             }
        }
     }
    

    (我只捕获“预期”异常,即不捕获invalidooperation等)
    我工作得很好,但在数据处理应用程序类型中,我通常使用上面的级别,如下所示:

    public bool TryProcessData() {
        if (!customerReader.TryReadCustomers())
            return false;
    
        var orders = webOrderReader.ReadNewOrders());
        if (orders == null)
            return false;
    
        if (!orderCreator.TryCreateNewOrder(order))
        ...
    
    }
    

    对我来说,这感觉就像回到了例外之前的时代。

    我应该抛出某种“AlreadyHandledException”而不是在顶层抛出一个空catch子句吗?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Maarten Bodewes    13 年前

    不要回到过去,而是用更高级别的异常来包装它。在这种情况下,应该定义readCustOrderDataException和ReadNewOrderException。这还有一个额外的好处,就是创建可读性很强的代码。创建一个新的异常并不难,如果您的语言有内部类,那么您可以创建一个公共内部类。

    最后,这取决于您是否应该返回布尔值,但我建议您在更高级别的方法中捕获自定义(选中)异常,该方法实际上需要布尔值,而不是之前。

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

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