In CsvHelper how to catch a conversion error and know what field and what row it happened in?

StackOverflow https://stackoverflow.com/questions/21609348

  •  08-10-2022
  •  | 
  •  

質問

I am using the class CsvReader successfully and am happy with it, however, the file that I consume is being produced by a group which changes column formats without letting me know.

So, one moment everything is working, then the next morning things break and the try catch block around csv.GetRecord<MyType>() catches the error and logs the error, however I can't gather any valuable info from the Exception instance. It just says: "The conversion cannot be performed." and the InnerException has nothing. Not very useful. I don't even know which one of my 150 columns are causing the problem.

Can you help me figure out how I can pinpoint which column in which row is causing the problem?

Thanks

役に立ちましたか?

解決 2

First of all, it seems that I need to catch CsvTypeConverterException.

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

I now know how to investigate what went wrong, but how do I make sure that that field is skipped but the rest of the fields in that row are converted, so that not the entire row is thrown away?

Thanks

他のヒント

Currently, there is no way to ignore errors at the field/property level. Your current options are these:

Look at the exception data.

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

Ignore reading exceptions. This is on a row level, though, not field. It will allow the whole file to still be read, and just ignore the rows that don't work. You can get a callback when an exception occurs.

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

CsvHelper has public 'Context' field in the CsvReader and there are all what needed for display a problem:

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;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top