-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Extend error message #960
Extend error message #960
Conversation
@jstarry Error is trigered only if named props are after [with props]. html! {
<MyComponent with props value=1 />
} I did not find any information in docs about using
html! {
<MyComponent value=1 with props />
} I'm receiving Thank you |
|
@jstarry It is looks like that error handling from L 401 to to L410 does not work at all html! {
<MyComponent type />
} You will see |
It should work. Your example doesnt work because you need an equals sign, see here https://github.com/captain-yossarian/yew-1/blob/3a196c3c7d6509ec74c5900b55da789727543361/crates/macro/src/html_tree/html_prop.rs#L16. That said, we should improve the error for your example as well! |
@jstarry Ready for review As for error handling for html! {
<MyComponent type />
}
/// OR
html! {
<MyComponent type= />
} I wold like to make it in separate PR, because for me, this condition if prop.label.to_string() == "type" {
return Err(syn::Error::new_spanned(&prop.label, "expected identifier"));
} does not work at all. |
@captain-yossarian great! Unfortunately, the macro tests were not running on CI for your PR. I just merged #965 to fix that. Could you please rebase this PR and fix the tests? It just involves:
|
392caea
to
e0b0684
Compare
@jstarry Done What do you think about updating contribution guide? For example: When you add the tests, please make sure you have updated |
while HtmlProp::peek(input.cursor()).is_some() { | ||
props.push(input.parse::<HtmlProp>()?); | ||
} | ||
if input.cursor().token_stream().to_string().contains("with") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could catch errors not related to the with
syntax like so:
error: Using special syntax `with props` along with named prop is not allowed
--> $DIR/html-component-fail.rs:63:26
|
63 | html! { <Child int=1 "with" /> };
| ^^^^^^
I'd prefer this approach:
if let Some(ident) = input.cursor().ident() {
if ident.0 == "with" {
// ...
}
}
@captain-yossarian the contributing guide changes sound great to me. I created an issue here: #967 |
@jstarry please take a look on my changes |
@@ -36,7 +36,7 @@ error: unexpected token | |||
58 | html! { <Child with props ref=() ref=() /> }; | |||
| ^^^ | |||
|
|||
error: unexpected token | |||
error: Using special syntax `with props` along with named prop is not allowed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that this error is misleading... It's not clear from this error message that the following is valid:
html! { <Child with props ref=() /> }
This is because ref=..
is a special prop and can be used together with with props
as long as it comes after. Note, I'm open to html! { <Child ref=() with props /> }
being valid as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I got confused which test case that error was for.
In any case, I think that for
html! { <Child with props ref=() ref=() /> };
we should use this error: "too many refs set"
ListProps { props, node_ref } | ||
} | ||
|
||
fn apply_edge_cases(props: &Vec<HtmlProp>) -> Result<(), syn::Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jstarry What do you think about refactor of this function ?
It looks like I have to apply same conditions for both WithProps and ListProps logic.
So, I created a HashMap with all edge cases.
For example: if you want apply only ref
edge case, you can pass a slice with one element "ref" as a second argument to apply_edge_cases
. This let you use same logic for both ListProps
and WithProps
.
If in the future, you would like to add more adge cases, you can only insert new [key, valye]
to the hash map.
I just don't want to copy/paste logic from one function to another.
Also, here you can concatenate all errors in one string and output it to the user.
If you think it is not Ok, you can check this 23bdf72
commit.
Here I just copied logic from one function to another, it covers all edge cases and it is not DRY
P.S. The code you see is a draft, it is not my final PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@captain-yossarian nice! Here are my thoughts:
It looks like I have to apply same conditions for both WithProps and ListProps logic.
Good point, how about we pull that common logic out of WithProps
and ListProps
and handle it Props
instead? I'm imagining something like:
- Parse list of props
- Parse
with props
- Parse list of props
- Check for double refs from 1. and 3.
So, I created a HashMap with all edge cases
I'm not convinced this is really helping much, I think the for loop and if statements that we had before were clearer. We don't need to generalize this too much.
I just don't want to copy/paste logic from one function to another.
Yeah, generally it's good to avoid copy/paste logic. I think in this case, we can avoid it by handling common paths at the Props
level
you can concatenate all errors in one string and output it to the user.
I think one error at a time is fine. Also, you can collect a list of results into one: https://doc.rust-lang.org/std/result/enum.Result.html#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this approach, I think we can allow ref
to come before with props
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jstarry I have a problem with props type.
return_type
function can catch all kind of errors. It works perfectly.
But it works only with let _ = Props::collect_props(input)?;
433 line
If I remove this line, app throw an error in this place: return Err(input.error("MY"));
464 line.
Do you have any thoughts why does it is happening?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@captain-yossarian yeah the issue is that you are consuming the ParseStream
in get_type
and so there are no tokens left to parse. Look at how Peek
implementations work. They use a cursor which can read without consuming any tokens from the ParseStream
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error: Using special syntax `with props` along with named prop is not allowed. This rule does not apply to special `ref` prop | ||
--> $DIR/html-component-fail.rs:65:27 | ||
| | ||
65 | html! { <Child ref=() with props /> }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test doesn't look right
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jstarry It is looks like currently on master if you use this approach, you will receive an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, currently on master this will cause an error. My concern is that the test error message is confusing for this test case:
"error: Using special syntax `with props` along with named prop is not allowed. This rule does not apply to special `ref` prop"
@jstarry Thank you for the help! :) |
1578218
to
41601e4
Compare
@jstarry Unfortunately, after resolving all merge conflicts,
|
e12364a
to
686c5d6
Compare
@captain-yossarian can you please rebase on (or merge) master and fix the |
Related to #664