give better error if required field of url join is invalid (#10589)

# Description
Fix #10506 by adding `ExpectedNonNull` `ShellError` if required field is
entered as `$nothing`, `null`, " ", etc.

This adds a new `ShellError`, `ExpectedNonNull`, taking the expected
type and span.

# User-Facing Changes
Will get a more helpful error in the case described by #10506. Examples:
```nushell
➜ {scheme: "", host: "github.com"} | url join
Error: nu:🐚:expected_non_null

  × Expected string found null.
   ╭─[entry #16:1:1]
 1 │ {scheme: "", host: "github.com"} | url join
   ·          ─┬
   ·           ╰── expected string, found null
   ╰────
```

```nushell
❯ {scheme: "https", host: null} | url join
Error: nu:🐚:expected_non_null

  × Expected string found null.
   ╭─[entry #19:1:1]
 1 │ {scheme: "https", host: null} | url join
   ·                         ──┬─
   ·                           ╰── expected string, found null
   ╰────
```

# Tests + Formatting
All pass.
This commit is contained in:
Marshall Bruner 2023-10-10 19:24:23 +02:00 committed by GitHub
parent dc3c34275d
commit 1402508416
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -223,12 +223,11 @@ impl UrlComponents {
}; };
} }
// a part from port and params all other keys are strings. // apart from port and params all other keys are strings.
match value.as_string() { let s = value.as_string()?; // If value fails String conversion, just output this ShellError
Ok(s) => { if !Self::check_empty_string_ok(&key, &s, value_span)? {
if s.trim().is_empty() { return Ok(self);
Ok(self) }
} else {
match key.as_str() { match key.as_str() {
"host" => Ok(Self { "host" => Ok(Self {
host: Some(s), host: Some(s),
@ -286,7 +285,7 @@ impl UrlComponents {
engine_state, engine_state,
&ShellError::GenericError( &ShellError::GenericError(
format!("'{key}' is not a valid URL field"), format!("'{key}' is not a valid URL field"),
format!("Remove '{key}' col from input record"), format!("remove '{key}' col from input record"),
Some(span), Some(span),
None, None,
vec![], vec![],
@ -296,8 +295,24 @@ impl UrlComponents {
} }
} }
} }
// Check if value is empty. If so, check if that is fine, i.e., not a required input
fn check_empty_string_ok(key: &str, s: &str, value_span: Span) -> Result<bool, ShellError> {
if !s.trim().is_empty() {
return Ok(true);
} }
_ => Ok(self), match key {
"host" => Err(ShellError::UnsupportedConfigValue(
"non-empty string".into(),
"empty string".into(),
value_span,
)),
"scheme" => Err(ShellError::UnsupportedConfigValue(
"non-empty string".into(),
"empty string".into(),
value_span,
)),
_ => Ok(false),
} }
} }