Skip Menu |

This queue is for tickets about the Text-CSV_XS CPAN distribution.

Report information
The Basics
Id: 115954
Status: resolved
Priority: 0/
Queue: Text-CSV_XS

People
Owner: Nobody in particular
Requestors: tsibley [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.23
Fixed in: 1.25



Subject: How do you detect a parsing error on the last line when using getline?
getline returns undef on failure but also at eof. Thus if the last line has a parsing error, a check such as: while (my $row = $csv->getline(...)) { ... } $csv->eof or $csv->error_diag doesn't have the desired effect. What's a robust and reasonable way to check for an error state when using getline? The following seems to work, but I'm not sure it's a good solution: unless ($csv->eof and ($csv->error_diag == 0 or $csv->error_diag == 2012)) { $csv->error_diag; } Thoughts?
I'd say use auto_diag. That is by far the safest way to always get the errors. I see you point, and will think about a more robust way to check for the state.
Done some tests (as you could have done too). On error, eof is not set In this file the last line clearly is in error (under default options): $ cat sandbox/test.csv a,b,c,d 1,2,3,4 2,3,4,5 3," "b" ",6,7 $ perl -MText::CSV_XS -MDP -wE'my$csv=Text::CSV_XS->new;open my$fh,"<","sandbox/test.csv";while(my$r=$csv->getline($fh)){say"@$r"};$csv->eof and say "EOF";say for $csv->error_diag' a b c d 1 2 3 4 2 3 4 5 2023 EIQ - QUO character not allowed 5 4 2 As you can see, the error is set, but EOF is not. Feel free to re-open the ticket if you can show me a situation where both error *and* EOF are set due to an error in the final line. Until then, I'll have to close this ticket as not a bug, and will keep with the docs recommendation: my $csv = Text::CSV_XS ({ binary => 1, auto_diag => 1 }); while (my $row = $csv->getline ($fh)) { # ... } $csv->eof or say "auto_diag should have shown you the error already";
At first I thought I was crazy and hadn't encountered what I thought I did. But then I was able to reproduce it minimally: $ cat badcsv.csv 1,bad to the bone,foo 2,"bad "to the" bone",bar 3,""bad to the bone"",baz $ cat badcsv.pl use strict; use 5.010; use Text::CSV_XS; my $csv = Text::CSV_XS->new({ binary => 1, allow_loose_escapes => 1 }); while (my $r = $csv->getline(\*STDIN)){ say "@$r"; } say "EOF" if $csv->eof; say join " ", $csv->error_diag; $ perl badcsv.pl < badcsv.csv 1 bad to the bone foo 2 bad "to the" bone bar EOF 2027 EIQ - Quoted field not terminated 26 3 2
Note that unsetting either "binary" or "allow_loose_escapes" stops EOF from being set. Setting "allow_loose_quotes" or other options don't seem to effect the outcome.
On Wed Jul 13 15:04:08 2016, TSIBLEY wrote: Show quoted text
> Note that unsetting either "binary" or "allow_loose_escapes" stops EOF > from being set. > > Setting "allow_loose_quotes" or other options don't seem to effect the > outcome.
See https://github.com/Tux/Text-CSV_XS/commit/a16c0d7e05ee438a1354f22419ccb9ba84fc9e0e and https://github.com/Tux/Text-CSV_XS/commit/7345656439fb535059980156fd08e4f1692d6830 --8<--- Note that if the parsing of the last line caused an error, C<eof> is still true. That means that if you are I<not> using L</auto_diag>, an idiom like while (my $row = $csv->getline ($fh)) { # ... } $csv->eof or $csv->error_diag; will I<not> report the error. You would have to change that to while (my $row = $csv->getline ($fh)) { # ... } +$csv->error_diag and $csv->error_diag; -->8--- or use csv ({ auto_diag => 1 });
Thanks! :)