-
Notifications
You must be signed in to change notification settings - Fork 889
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
refactor - improved error regarding issue "Better error message #6302" #6310
Conversation
src/config/mod.rs
Outdated
pub(super) fn from_toml(toml: &str, dir: &Path,file_path : &Path) -> Result<Config, String> { | ||
Self::from_toml_for_style_edition(toml, dir,file_path, None, None, None) |
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.
We don't need to pass both dir
and file_path
. The dir
can easily be derived from the file path.
src/config/mod.rs
Outdated
dir: &Path, | ||
file_path: &Path, |
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.
Same goes for this. We don't need to pass both the dir
and file_path
. We can derive the dir
from the file_path
.
i cant figure out why my tests are failing, could you please guide me through this? |
It looks like the self-tests didn't pass. Since it's important for the rustfmt source code to adhere to the same formatting style that it enforces, the self-test runs rustfmt on its own codebase. You can find more details in the Contributing.md. To resolve this, you might want to try running Hope this helps! |
@ytmimi i think its ready for review now, thank you |
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.
Thanks for continuing to look into this. I've left a few comments inline. Also, I think it would be great if we could add a unit test similar to those defined here, where we call the rustfmt binary and check the content of stdout / stderr.
In this case we can create a new config file in tests/config
that will trigger the error, and we can call rustfmt with the --config-path
argument and validate that we see our expected error message in stderr.
Also, one more note. The rustfmt team strongly discourages merge commits. Please rebase your branch to bring it up to date when you get a chance.
src/config/mod.rs
Outdated
Ok(parsed_config.to_parsed_config(style_edition, edition, version, dir)) | ||
Ok(parsed_config.to_parsed_config(style_edition, edition, version, file_path)) |
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.
Can you double check what PartialConfig::to_parsed_config
does with the dir
argument. Although the types match up before the method expected a directory path and now we're passing a file path so that could change behavior. We probably need to derive the dir
from the file path here.
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.
Correct me if i am wrong, to_parsed_config()
only uses dir
arguement for fill_from_parsed_config(self,dir)
pub(super) fn to_parsed_config(
self,
style_edition_override: Option<StyleEdition>,
edition_override: Option<Edition>,
version_override: Option<Version>,
dir: &Path,
) -> Config {
Config::default_for_possible_style_edition(
style_edition_override.or(self.style_edition),
edition_override.or(self.edition),
version_override.or(self.version),
)
.fill_from_parsed_config(self, dir)
}
}
and
fn fill_from_parsed_config(mut self, parsed: PartialConfig, dir: &Path) -> Config {
$(
if let Some(option_value) = parsed.$i {
let option_stable = self.$i.3;
if $crate::config::config_type::is_stable_option_and_value(
stringify!($i), option_stable, &option_value
) {
self.$i.1 = true;
self.$i.2 = option_value;
}
}
)+
self.set_heuristics();
self.set_ignore(dir);
self.set_merge_imports();
self.set_fn_args_layout();
self.set_hide_parse_errors();
self.set_version();
self
}
The dir
parameter is used only in the self.set_ignore(dir)
method call, i think its to specifiy which files or directories to ignore based on the provided directory path.
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.
Thanks for looking into this. Given that code down the stack needs the dir
we need to pass that along.
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.
Ok(parsed_config.to_parsed_config(style_edition, edition, version, file_path.parent().unwrap_or(Path::new(""))))
can we refactor that statement to this so that we can also pass dir
?
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 think it's fine to just call file_path.parent().unwrap()
since that's what from_toml_path
did before your change.
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.
but if its unwrap() . wont we pass a None value if its empty? and isnt that 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.
i have followed your approach and tried just using unwrap() and then tested it, i got this output
---- config::test::test_unstable_from_toml stdout ----
thread 'config::test::test_unstable_from_toml' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
---- config::test::deprecated_option_merge_imports::test_new_overridden stdout ----
thread 'config::test::deprecated_option_merge_imports::test_new_overridden' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
---- config::test::deprecated_option_merge_imports::test_both_set stdout ----
thread 'config::test::deprecated_option_merge_imports::test_both_set' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- config::test::deprecated_option_merge_imports::test_old_overridden stdout ----
thread 'config::test::deprecated_option_merge_imports::test_old_overridden' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
---- config::test::deprecated_option_merge_imports::test_old_option_set stdout ----
thread 'config::test::deprecated_option_merge_imports::test_old_option_set' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
---- config::test::test_was_set stdout ----
thread 'config::test::test_was_set' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
---- config::test::use_small_heuristics::test_array_width_config_exceeds_max_width stdout ----
thread 'config::test::use_small_heuristics::test_array_width_config_exceeds_max_width' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
---- config::test::use_small_heuristics::test_attr_fn_like_width_config_exceeds_max_width stdout ----
thread 'config::test::use_small_heuristics::test_attr_fn_like_width_config_exceeds_max_width' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
---- config::test::use_small_heuristics::test_chain_width_config_exceeds_max_width stdout ----
thread 'config::test::use_small_heuristics::test_chain_width_config_exceeds_max_width' panicked at src/config/mod.rs:401:40:
called `Option::unwrap()` on a `None` value
Am i missing something?
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.
@ytmimi , what approach should i prefer here?
src/config/mod.rs
Outdated
let config_file_path_str = file_path.to_string_lossy(); | ||
|
||
let err_msg = format!( | ||
"The file `{}` failed to parse.\n\ | ||
Error details: {}\n\ | ||
Help: Ensure that the configuration file at `{}` is correctly formatted.", | ||
config_file_path_str, e, config_file_path_str | ||
); | ||
|
||
Err(err_msg) |
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.
We should still add the err_msg
to the err
String and return that since it might contain additional error details. Also, I think we can simplify the error message as follows since you've already told the user the path to the file on the first line:
let err_msg = format!(
"The file `{}` failed to parse.\n Error details: {e}",
file_path.display()
);
err.push_str(&err_msg)
Err(err)
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 i agree that your approach is much better and is also working, i have changed the code accordingly
okay, so we have to write a test case in
would it be better if i do once we have finalized all the refactoring? |
Yeah, thats right.
Sure. Just wanted to make you aware of our stance on merge commits. |
@ytmimi , why trying to test this issue, i faced two issues
we get the entire path . so we cant test it that way as the absolute path will change for every person. so i think we might have to refactor the code where it will only present the path from the main project directory?
the |
How exactly are you trying to test this? I think it should be doable. If you could add a commit with your test code that would be helpful for me to review and provide some suggestions.
If you look at the original issue the |
@ytmimi , i have added the commit, could you please check it and let me know where i am getting it wrong? |
tests/rustfmt/main.rs
Outdated
#[test] | ||
fn rustfmt_error_improvement_regarding_invalid_toml() { | ||
// See also https://github.com/rust-lang/rustfmt/issues/6302 | ||
let args = ["--config-path", "tests/config/issue-6302.toml"]; | ||
let (_stdout, stderr) = rustfmt(&args); | ||
|
||
let expected_error_message = "The file `rustfmt/tests/config/issue-6302.toml` failed to parse.\n Error details: invalid type: integer `2019`, expected string in `edition`"; | ||
|
||
assert!( | ||
stderr.contains(expected_error_message), | ||
"Unexpected error message.\nExpected:\n{}\nGot:\n{}", | ||
expected_error_message, | ||
stderr | ||
); | ||
} |
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.
Nit: add a space between the test and the one above it.
Here's how you can write the test to pass:
#[test]
fn rustfmt_error_improvement_regarding_invalid_toml() {
// See also https://github.com/rust-lang/rustfmt/issues/6302
let invalid_toml_config = "tests/config/issue-6302.toml";
let args = ["--config-path", invalid_toml_config];
let (_stdout, stderr) = rustfmt(&args);
let toml_path = Path::new(invalid_toml_config).canonicalize().unwrap();
let expected_error_message = format!("The file `{}` failed to parse", toml_path.display());
assert!(stderr.contains(&expected_error_message));
}
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 have updated it , thank you
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.
Let me know if you'd like to squash the commits / rebase the PR or if you'd rather I just squash the commits on the merge.
i had left a comment regarding |
src/config/mod.rs
Outdated
Ok(parsed_config.to_parsed_config( | ||
style_edition, | ||
edition, | ||
version, | ||
file_path.parent().unwrap_or(Path::new("")), | ||
)) |
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.
As mentioned in #6310 (comment) the previous logic was to unwrap
, which is going to panic if we can't get a directory from the file, and i think that's fine (and probably very unlikely to panic in practice).
However we can also just return early with an error:
let dir = file_path.patent()
.ok_or_else(|| format!("failed to get parent directory for {}", file_path.display))?;
Ok(parsed_config.to_parsed_config(
style_edition,
edition,
version,
dir,
))
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 have pushed the code now, if the tests past , i will then rebase the code and i think we are good to merge after that?
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.
the tests failed
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, you likely need to update all the tests that just pass Path::new("")
. to Config::from_toml
since we've updated the semantics to pass a file path instead.
let config = Config::from_toml(toml, Path::new("")).unwrap();
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.
so i need to update tests in config dir ?
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.
@rufevean I'd recommend you look into the details of the CI failures, and fix the impacted tests. If it turns out to be more involved than what I just mentioned let me know.
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.
got it, thank you
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.
@ytmimi , i dont know if this is the right approach but i changed
let config = Config::from_toml(toml, Path::new("")).unwrap();
to
let config = Config::from_toml(toml, Path::new(".")).unwrap();
to have current dir as parent dir? and tests got passed
src/config/mod.rs
Outdated
let config = Config::from_toml("hard_tabs = true", Path::new("")).unwrap(); | ||
let config = Config::from_toml("hard_tabs = true", Path::new(".")).unwrap(); |
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.
Let's change this to a file path to better convey that from_toml
now expects a file path instead of a directory.
let config = Config::from_toml("hard_tabs = true", Path::new("./rustfmt.toml")).unwrap();
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.
should i do this for every test that takes from_toml
or just this?
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.
All of them please
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.
updated , thank you
Turns out there were still a few things that we're working on. Dismissing the old review for now
@ytmimi can we rebase and merge this now? |
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.
@rufevean yes, this should be ready now. I'll give you an opportunity to rebase this PR and squash the commits if you'd like to clean up the final commit or I can take care of it. Let me know what you'd prefer.
@ytmimi i think i did something wrong, i rebased it and squashed all my commits into 1. but i can see other's commits here . |
Yeah, definitely doesn't look right. You should be able to get back to the commit before the rebase if you check the |
7930f4f
to
23d9d57
Compare
@ytmimi , i tried squashing it again and deleting the commits that i dont want to include but even then there are some conflicts . its better if you may handle it. thank you |
hmm weird, when I tried to update your branch GitHub marked me as closing the PR 🤔 |
closes #6302