diff --git a/crates/nu-command/src/commands/core_commands/if_.rs b/crates/nu-command/src/commands/core_commands/if_.rs index 0eba1c321..85451ec19 100644 --- a/crates/nu-command/src/commands/core_commands/if_.rs +++ b/crates/nu-command/src/commands/core_commands/if_.rs @@ -101,17 +101,14 @@ fn if_command(args: CommandArgs) -> Result { //FIXME: should we use the scope that's brought in as well? let condition = evaluate_baseline_expr(cond, &context); - match condition { + let result = match condition { Ok(condition) => match condition.as_bool() { Ok(b) => { - let result = if b { + if b { run_block(&then_case.block, &context, input, external_redirection) } else { run_block(&else_case.block, &context, input, external_redirection) - }; - context.scope.exit_scope(); - - result + } } Err(e) => Ok(OutputStream::from_stream( vec![UntaggedValue::Error(e).into_untagged_value()].into_iter(), @@ -120,13 +117,16 @@ fn if_command(args: CommandArgs) -> Result { Err(e) => Ok(OutputStream::from_stream( vec![UntaggedValue::Error(e).into_untagged_value()].into_iter(), )), - } + }; + context.scope.exit_scope(); + result } #[cfg(test)] mod tests { use super::If; use super::ShellError; + use nu_test_support::nu; #[test] fn examples_work_as_expected() -> Result<(), ShellError> { @@ -134,4 +134,21 @@ mod tests { test_examples(If {}) } + + #[test] + fn if_doesnt_leak_on_error() { + let actual = nu!( + ".", + r#" + def test-leak [] { + let var = "hello" + if 0 == "" {echo ok} {echo not} + } + test-leak + echo $var + "# + ); + + assert!(actual.err.contains("unknown variable")); + } }