在CsvHelper中,如何捕获转换错误并知道发生错误的字段和行数?

37

我成功地使用了 CsvReader 类,并对其感到满意,但是我需要读取的文件是由一个不通知我的团队生成的,他们会更改列格式。

所以,有时候一切都正常,然后第二天就会出现问题,csv.GetRecord<MyType>() 中的 try catch 块捕获错误并记录错误,但是我无法从 Exception 实例中收集任何有价值的信息。它只说:“无法执行转换”,而且 InnerException 没有任何内容。这没有什么用。我甚至不知道我的 150 个列中的哪一个引起了问题。

你能帮我找出是哪个行中的哪个列引起了问题吗?

谢谢.

3个回答

51

目前,还没有一种方法可以在字段/属性级别上忽略错误。 您当前的选项如下:

查看异常数据。

catch( Exception ex )
{
    // This contains useful information about the error.
    ex.Data["CsvHelper"];
}

忽略读取异常。这是在行级别上,而不是字段级别。它将允许整个文件仍然可以被读取,只是忽略掉无法工作的行。当发生异常时,您可以得到回调。

csv.Configuration.IgnoreReadingExceptions = true;
csv.Configuration.ReadingExceptionCallback = ( ex, row ) =>
{
    // Do something with the exception and row data.
    // You can look at the exception data here too.
};

12

首先,似乎我需要捕获CsvTypeConverterException异常。

 while (csv.Read())
    {
       try
       {    
          var record = csv.GetRecord<MyType>();    
       }
       catch (CsvTypeConverterException ex)
       {
         //ex.Data.Values has more info...
       }
    }

我现在知道如何调查出错的原因,但是如何确保跳过那个字段,而将该行中其余字段转换,以便不会丢弃整行数据?

谢谢。


1
你可能已经想到了,但回答你如何跳过记录的问题,请检查配置“ShouldSkipRecord”,您可以设置回调函数在这种情况下被调用。 - firepol
似乎在 while 循环中放置 try/catch 会极大地减慢整个过程。我注意到这一点是在循环遍历包含约 500k 行的 .csv 文件时。 - Omar Himada

1

CsvHelperCsvReader中有一个公共的“Context”字段,其中包含显示问题所需的所有内容:

try
{
    var records = csvReader.GetRecords<MyType>().ToList();
}
catch (CsvHelperException e)
{
    Console.WriteLine($"{e.Message} " + (e.InnerException == null ? string.Empty : e.InnerException.Message));
    Console.WriteLine($"Row: {csvReader.Context.Row}; RawLine: {csvReader.Context.RawRecord}");
    if (csvReader.Context.CurrentIndex >= 0 &&
        csvReader.Context.CurrentIndex < csvReader.Context.HeaderRecord.Length)
    {
        Console.WriteLine($"Column: {csvReader.Context.CurrentIndex}; ColumnName: {csvReader.Context.HeaderRecord[csvReader.Context.CurrentIndex]}");
    }
    throw;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接