forked from extern/nushell
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:
parent
dc3c34275d
commit
1402508416
@ -223,81 +223,96 @@ 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)
|
}
|
||||||
|
match key.as_str() {
|
||||||
|
"host" => Ok(Self {
|
||||||
|
host: Some(s),
|
||||||
|
..self
|
||||||
|
}),
|
||||||
|
"scheme" => Ok(Self {
|
||||||
|
scheme: Some(s),
|
||||||
|
..self
|
||||||
|
}),
|
||||||
|
"username" => Ok(Self {
|
||||||
|
username: Some(s),
|
||||||
|
..self
|
||||||
|
}),
|
||||||
|
"password" => Ok(Self {
|
||||||
|
password: Some(s),
|
||||||
|
..self
|
||||||
|
}),
|
||||||
|
"path" => Ok(Self {
|
||||||
|
path: Some(if s.starts_with('/') {
|
||||||
|
s
|
||||||
} else {
|
} else {
|
||||||
match key.as_str() {
|
format!("/{s}")
|
||||||
"host" => Ok(Self {
|
}),
|
||||||
host: Some(s),
|
..self
|
||||||
..self
|
}),
|
||||||
}),
|
"query" => {
|
||||||
"scheme" => Ok(Self {
|
if let Some(q) = self.query {
|
||||||
scheme: Some(s),
|
if q != s {
|
||||||
..self
|
// if query is present it means that also params_span is set.
|
||||||
}),
|
return Err(ShellError::IncompatibleParameters {
|
||||||
"username" => Ok(Self {
|
left_message: format!("Mismatch, query param is: {s}"),
|
||||||
username: Some(s),
|
left_span: value.span(),
|
||||||
..self
|
right_message: format!("instead qs from params is: {q}"),
|
||||||
}),
|
right_span: self.params_span.unwrap_or(Span::unknown()),
|
||||||
"password" => Ok(Self {
|
});
|
||||||
password: Some(s),
|
|
||||||
..self
|
|
||||||
}),
|
|
||||||
"path" => Ok(Self {
|
|
||||||
path: Some(if s.starts_with('/') {
|
|
||||||
s
|
|
||||||
} else {
|
|
||||||
format!("/{s}")
|
|
||||||
}),
|
|
||||||
..self
|
|
||||||
}),
|
|
||||||
"query" => {
|
|
||||||
if let Some(q) = self.query {
|
|
||||||
if q != s {
|
|
||||||
// if query is present it means that also params_span is set.
|
|
||||||
return Err(ShellError::IncompatibleParameters {
|
|
||||||
left_message: format!("Mismatch, query param is: {s}"),
|
|
||||||
left_span: value.span(),
|
|
||||||
right_message: format!("instead qs from params is: {q}"),
|
|
||||||
right_span: self.params_span.unwrap_or(Span::unknown()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
query: Some(format!("?{s}")),
|
|
||||||
query_span: Some(value.span()),
|
|
||||||
..self
|
|
||||||
})
|
|
||||||
}
|
|
||||||
"fragment" => Ok(Self {
|
|
||||||
fragment: Some(if s.starts_with('#') {
|
|
||||||
s
|
|
||||||
} else {
|
|
||||||
format!("#{s}")
|
|
||||||
}),
|
|
||||||
..self
|
|
||||||
}),
|
|
||||||
_ => {
|
|
||||||
nu_protocol::report_error_new(
|
|
||||||
engine_state,
|
|
||||||
&ShellError::GenericError(
|
|
||||||
format!("'{key}' is not a valid URL field"),
|
|
||||||
format!("Remove '{key}' col from input record"),
|
|
||||||
Some(span),
|
|
||||||
None,
|
|
||||||
vec![],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
query: Some(format!("?{s}")),
|
||||||
|
query_span: Some(value.span()),
|
||||||
|
..self
|
||||||
|
})
|
||||||
}
|
}
|
||||||
_ => Ok(self),
|
"fragment" => Ok(Self {
|
||||||
|
fragment: Some(if s.starts_with('#') {
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
format!("#{s}")
|
||||||
|
}),
|
||||||
|
..self
|
||||||
|
}),
|
||||||
|
_ => {
|
||||||
|
nu_protocol::report_error_new(
|
||||||
|
engine_state,
|
||||||
|
&ShellError::GenericError(
|
||||||
|
format!("'{key}' is not a valid URL field"),
|
||||||
|
format!("remove '{key}' col from input record"),
|
||||||
|
Some(span),
|
||||||
|
None,
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user