From d8c4565413b4f75829fdeb9ac7605611a059c312 Mon Sep 17 00:00:00 2001 From: Sosthene-Guedon <51865119+Sosthene-Guedon@users.noreply.github.com> Date: Mon, 16 Mar 2020 18:32:02 +0100 Subject: [PATCH] Csv errors (#1490) * Add error message for csv parsing failures * Add csv error prettyfier * Improve readability of the error Line 2: error is easier to understand than: Line 2, error * Remove unnecessary use of the format! macro Replacing it with .to_string() fixes a clippy warning * Improve consistency with JSON parsing errors --- .../src/commands/from_delimited_data.rs | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/crates/nu-cli/src/commands/from_delimited_data.rs b/crates/nu-cli/src/commands/from_delimited_data.rs index 86854227e..2e931885c 100644 --- a/crates/nu-cli/src/commands/from_delimited_data.rs +++ b/crates/nu-cli/src/commands/from_delimited_data.rs @@ -1,5 +1,5 @@ use crate::prelude::*; -use csv::ReaderBuilder; +use csv::{ErrorKind, ReaderBuilder}; use nu_errors::ShellError; use nu_protocol::{Primitive, ReturnSuccess, TaggedDictBuilder, UntaggedValue, Value}; @@ -58,8 +58,11 @@ pub fn from_delimited_data( } x => yield ReturnSuccess::value(x), }, - Err(_) => { - let line_one = format!("Could not parse as {}", format_name); + Err(err) => { + let line_one = match pretty_csv_error(err) { + Some(pretty) => format!("Could not parse as {} ({})", format_name,pretty), + None => format!("Could not parse as {}", format_name), + }; let line_two = format!("input cannot be parsed as {}", format_name); yield Err(ShellError::labeled_error_with_secondary( line_one, @@ -74,3 +77,26 @@ pub fn from_delimited_data( Ok(stream.to_output_stream()) } + +fn pretty_csv_error(err: csv::Error) -> Option { + match err.kind() { + ErrorKind::UnequalLengths { + pos, + expected_len, + len, + } => { + if let Some(pos) = pos { + Some(format!( + "Line {}: expected {} fields, found {}", + pos.line(), + expected_len, + len + )) + } else { + Some(format!("Expected {} fields, found {}", expected_len, len)) + } + } + ErrorKind::Seek => Some("Internal error while parsing csv".to_string()), + _ => None, + } +}