-
Notifications
You must be signed in to change notification settings - Fork 908
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
rustfmt: Make error handling more idiomatic #914
Conversation
I'll reopen this in a bit; missed some things. |
Ugh I pushed and can't reopen. Sadness. |
Oh but now I can? |
781c79e
to
383b69c
Compare
use std::fs::{self, File}; | ||
use std::io::{self, ErrorKind, Read, Write}; | ||
use std::path::{Path, PathBuf}; | ||
use std::str::FromStr; | ||
|
||
use getopts::{Matches, Options}; | ||
|
||
type Error = Box<error::Error + Send + Sync>; |
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.
Do we need this error type? Can we just use String as our error type?
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 try!
macro won't work with String
unless we put .map_err(ToString::to_string)
or something like that all over. The Box<Error+Send+Sync
allows String
or any other Error
impl.
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.
In which case can we have FmtError rather than just Error for the same reason as Result below.
Thanks for the PR! I like the overall thrust of moving towards I'm not keen on the refactoring in the second commit. That seems to make the match slightly more complex (IMO) by adding an extra branch, although it's not a big difference either way. |
This commit replaces the `Operation::InvalidInput` variant with `Result`, and uses the `try!()` macro instead of explicit matching.
For now, this is me peeling off bits of my work on #434, where I was getting frustrated by the error handling in the binary. Let me know if you want a bit of "advance warning" on what I'm working on there, or if peeling self-contained bits as I've done here and, eg, in #857, #891, #910 is ok. I do have a plan to use |
383b69c
to
e7220e1
Compare
Peeling bits off is fine, I think. If you have any huge changes in mind, it might be better to discuss in advance, but I think you know the code well enough that small to medium things should be fine. It is kind of annoying about the String/Error thing, but it sounds like limitation of |
My reading of the RFC is it'lI still go through
I think you could get the behavior you want with a blanket |
This commit changes the match in `lookup_project_file` to use pattern guards.
e7220e1
to
7242735
Compare
Runs afoul of coherence. |
// `rustfmt.toml`. | ||
Ok(ref md) if md.is_file() => return Ok(Some(config_file)), | ||
// Return the error if it's something other than `NotFound`; otherwise we didn't find | ||
// the project file yet, and continue searching. | ||
Err(e) => { | ||
if e.kind() != ErrorKind::NotFound { |
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 you can legitimately get ErrorKind::PermissionDenied
here. Maybe it makes sense to return Ok(None)
for an unknown 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 think you can legitimately get
ErrorKind::PermissionDenied
here.
I think that erroring out makes more sense. It is more likley that they've borked their permissions than they actually want an unreadable file named rustfmt.toml
to be in the tree.
Maybe it makes sense to return
Ok(None)
for an unknown error?
I don't think so. If somone has a project rustfmt.toml
file and there's a filesystem hiccup, I don't think they'd expect or want their project reformatted according to the formating defaults.
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 a quick note, this PR is a refactor and isn't intended to change any user visible behavior.)
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.
It is more likley that they've borked their permissions than they actually want an unreadable file named rustfmt.toml to be in the tree.
I meant a hypothetical use case when the user doesn't have rustfmt.toml
at all, but also doesn't have read permissions outside the home directory. For this use case, this would Err(PermissionDenied)
instead of reformatting with default settings.
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.
fs::metadata()
is stat(2)
on unix, which requires search permission on the path prefix rather than read permission on the file. As I understand it, it's not possible to have a situation where calling it would succeed at a lower level in the path hierarchy but fail at a higher level.
I don't know enough about Windows to say anything about how permissions work there.
(Moved comment to be a "line note" at #914 (comment)) |
@nrc ping! Is there anything else you'd like done here? |
Looks good, thanks! |
These commits improve error handling in the
rustfmt
binary moreidiomatic by
Operation::InvalidInput
variant withResult
try!()
macro instead of explicit matching