The Wayback Machine - https://web.archive.org/web/20201201174357/https://github.com/nushell/nushell/issues/2512
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic while adding Date with Duration #2512

Open
arnaudgolfouse opened this issue Sep 7, 2020 · 7 comments
Open

Panic while adding Date with Duration #2512

arnaudgolfouse opened this issue Sep 7, 2020 · 7 comments
Assignees

Comments

@arnaudgolfouse
Copy link

@arnaudgolfouse arnaudgolfouse commented Sep 7, 2020

Describe the bug
If we try to add a Duration to a Date, like so :
ls | get modified | = $it + 1000000000000000000yr
Then a panic occur if the Duration is too big (like here), or if the result overflows.

From what I can gather, these originate in nu-data/src/value.rs, when adding Primitive::Date to Primitive::Duration.

To Reproduce

ls | get modified | = $it + 1000000000000000000yr
thread 'main' panicked at 'Could not convert nushell Duration into chrono Duration.: ShellError { error: Diagnostic(ShellDiagnostic { diagnostic: Diagnostic { severity: Error, code: None, message: "Internal duration conversion overflow.", labels: [Label { style: Primary, file_id: 0, range: 0..0, message: "duration overflow" }], notes: [] } }), cause: None }', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/nu-data-0.19.0/src/value.rs:192:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

or

ls | get modified | = $it + 100000000000yr
thread 'main' panicked at 'Duration::seconds out of bounds', ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/macros.rs:13:23
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Expected behavior
Either perform the operation with overflow, or display an error message. I guess a third option would be changing Date so it is unbounded.

Configuration :

  • OS : Ubuntu 18.04
  • Nu version : 0.19.0
  • Optional features : default
@samuelvanderwaal
Copy link
Contributor

@samuelvanderwaal samuelvanderwaal commented Sep 8, 2020

I'm interested in taking on this issue if no one else is working on it.

@JosephTLyons
Copy link
Collaborator

@JosephTLyons JosephTLyons commented Sep 8, 2020

Hey @samuelvanderwaal, went ahead and assigned this to you. There's no pressure here either if you end up changing your mind, just let us know.

@samuelvanderwaal
Copy link
Contributor

@samuelvanderwaal samuelvanderwaal commented Sep 8, 2020

I've had a look at the code and the panic is happening here

// nu-data/value.rs
(Primitive::Date(x), Primitive::Duration(_)) => {
                let result = match operator {
                    Operator::Plus => {
                        // FIXME: Not sure if I could do something better with the Span.
                        let y = Primitive::into_chrono_duration(rhs.clone(), Span::unknown())
                               .expect("Could not convert nushell Duration into chrono Duration.");
                        Ok(x.checked_add_signed(y).expect("Data overflow."))
                    }
                    _ => Err((left.type_name(), right.type_name())),
                }?;
                Ok(UntaggedValue::Primitive(Primitive::Date(result)))
            }

when into_chrono_duration experiences an overflow and returns a ShellError:

// nu-protocol/value/primitive.rs
 pub fn into_chrono_duration(self, span: Span) -> Result<chrono::Duration, ShellError> {
        match self {
            Primitive::Duration(duration) => {
                let (secs, nanos) = duration.div_rem(&BigInt::from(NANOS_PER_SEC));
                let secs = match secs.to_i64() {
                    Some(secs) => secs,
                    None => {
                        return Err(ShellError::labeled_error(
                            "Internal duration conversion overflow.",
                            "duration overflow",
                            span,
                        ))
                    }
                };
. . .

A very simple fix is to match on the Result in nu-data/value.rs but raises the issue of how to handle the ShellError as the function signature expects static str so it can create a ShellError:CoerceError:

            (Primitive::Date(x), Primitive::Duration(_)) => {
                let result = match operator {
                    Operator::Plus => {
                        // FIXME: Not sure if I could do something better with the Span.
                        match Primitive::into_chrono_duration(rhs.clone(), Span::unknown()) {
                            Ok(y) => Ok(x.checked_add_signed(y).expect("Data overflow.")),
                            Err(_) => Err(("Date", "Duration overflow")),
                        }
                    }
                    _ => Err((left.type_name(), right.type_name())),
                }?;
                Ok(UntaggedValue::Primitive(Primitive::Date(result)))
            }

I've had a look through nu-errors but don't fully grok the logic for the different errors and their relations. Is there some magic for converting between error types here or do I need to look at refactoring the places that call compute_value so as not to assume they will always have a CoerceError?

@samuelvanderwaal
Copy link
Contributor

@samuelvanderwaal samuelvanderwaal commented Sep 8, 2020

Also, if you prefer to iterate through a PR I can create one instead of dialoging in the issue thread here.

@samuelvanderwaal
Copy link
Contributor

@samuelvanderwaal samuelvanderwaal commented Sep 18, 2020

@JosephTLyons changing all the places that call compute_values() looks like a pretty large refactor so that's probably not what we want. Do you have any thoughts on how to handle this error or would it be better to handle the overflow some other way (e.g. just perform the operation with the overflow).

@JosephTLyons
Copy link
Collaborator

@JosephTLyons JosephTLyons commented Sep 25, 2020

@samuelvanderwaal, I'm really sorry about my absence here. I've been interviewing for multiple jobs and haven't had a lot of free time for Nushell. That being said, I really don't know the best way of moving forward on this issue currently. Maybe @jonathandturner or @thegedge would know of a good way to move forward.

@samuelvanderwaal
Copy link
Contributor

@samuelvanderwaal samuelvanderwaal commented Sep 25, 2020

No worries! I talked to Jonathan on Discord and will open a PR when I get a chance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.