Skip to content
This repository was archived by the owner on May 20, 2020. It is now read-only.

Error-chain -> failure #202

Merged
merged 4 commits into from
Nov 27, 2017
Merged

Error-chain -> failure #202

merged 4 commits into from
Nov 27, 2017

Conversation

steveklabnik
Copy link
Owner

This PR ports us from error-chain to @withoutboats' failure crate.

I'm done for the day so there's probably CI failures and such, but I wanted to toss this up there so that everyone can see.

/cc @aturon @alexcrichton

@mgattozzi
Copy link
Contributor

@steveklabnik curious is there a reason to move towards that over error-chain?

src/lib.rs Outdated
@@ -172,9 +181,9 @@ pub fn build(config: &Config, artifacts: &[&str]) -> Result<()> {
.stderr(Stdio::piped())
.spawn()
.map_err(|e| if e.kind() == io::ErrorKind::NotFound {
Error::with_chain(e, format!("frontend `{}` not found", frontend))
format_err!("frontend `{}` not found", frontend).into()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you could use chain() to keep the context here?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, what's chain()? I don't see it in failure's docs

Copy link
Contributor

@euclio euclio Oct 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it's been renamed to context? It looks like it works slightly differently than chain_err did in error_chain? Hard to say without trying it 😂

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea I renamed it to context. You could do e.context(format!(...)).into() here.

src/lib.rs Outdated
@@ -196,8 +205,8 @@ pub fn build(config: &Config, artifacts: &[&str]) -> Result<()> {

/// Run all documentation tests.
pub fn test(config: &Config) -> Result<()> {
let doc_json = File::open(config.documentation_path()).chain_err(
|| "could not find generated documentation",
let doc_json = File::open(config.documentation_path()).map_err(|_|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

@euclio
Copy link
Contributor

euclio commented Oct 25, 2017

This looks interesting!

@steveklabnik
Copy link
Owner Author

curious is there a reason to move towards that over error-chain?

It's speculated that this kind of library may be preferable to error-chain overall; I wanted to give it a shot to see what the diff looks like. I think I personally prefer it, but the only way to find out is to give it a try.

@mgattozzi
Copy link
Contributor

Awesome!

@steveklabnik
Copy link
Owner Author

@withoutboats while working on the test part of this PR,

    = note: expected type `std::result::Result<_, failure::Error>`
               found type `std::result::Result<_, failure::Context<InvalidDirective>>`

Do you have to do something specific to use Context? It doesn't implement Error?

@withoutboats
Copy link

Context implements Fail; to get an Error all Failures have to be cast using ? or into().

@steveklabnik
Copy link
Owner Author

Thanks boats!

Now our test is failing because of the way we test the context; I suspect that I have to update the macro in some way. More work needed.

@euclio
Copy link
Contributor

euclio commented Nov 6, 2017

In this case, it might just be better to check that the cause is the expected type and always return an InvalidDirective failure from parse_test?

@steveklabnik steveklabnik force-pushed the failure branch 2 times, most recently from ea4870c to 5bace42 Compare November 22, 2017 15:26
@steveklabnik
Copy link
Owner Author

I've rebased this, and it compiles, but has test failures about not being able to find the source test crates. Hrm.

@steveklabnik
Copy link
Owner Author

Ohh interesting! https://travis-ci.org/steveklabnik/rustdoc/jobs/305812561

even though #203 passed, it's now failing. So it's likely that PR, not this one.... @euclio any ideas?

@euclio
Copy link
Contributor

euclio commented Nov 22, 2017

Failing on master too. Probably related to a change in how the analysis is generated. I did a quick test and it should be fixable by updating rls-analysis and rls-data, though there's an unrelated failure in structs.rs as well.

@steveklabnik
Copy link
Owner Author

ah, that makes perfect sense.

ill dig in.

@steveklabnik
Copy link
Owner Author

Updated and rebased, still failing. I must have missed something somewhere...

@steveklabnik
Copy link
Owner Author

oh wait looks like a bad rebase....

@steveklabnik
Copy link
Owner Author

Got master passing, this seems to reintroduce it. Hmmmmmmmmm

failure is becoming the de-facto error handling crate.
@steveklabnik
Copy link
Owner Author

@mgattozzi @euclio okay I think this is ready for a review, maybe you'll spot where I messed up. @withoutboats if you have a second as well, that'd be nice.

tests/source.rs Outdated

Directive::Has(regex)
}
"matches" => {
ensure!(args.len() == 2, "not enough arguments");
if args.len() == 2 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be if args.len() != 2

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol oops

tests/source.rs Outdated

Directive::Matches(value)
}
"assert" => {
ensure!(args.len() == 1, "expected 1 argument");
if args.len() == 1 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be if args.len() != 1

@steveklabnik
Copy link
Owner Author

Awesome, thank you! Of course I messed that up... that leads to just one failure now.

tests/source.rs Outdated
@@ -391,7 +413,7 @@ fn parse_test(line: &str) -> Option<Result<TestCase>> {
if let Some(caps) = DIRECTIVE_RE.captures(line) {
let directive = &caps["directive"];
let result = parse_directive(directive, &caps["args"], caps.name("negated").is_some())
.chain_err(|| ErrorKind::InvalidDirective(line.into()));
.map_err(|e| e.context(InvalidDirective { d: line.into() }).into());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the context is backwards here. I think that parse_test should return Option<Result<TestCase, InvalidDirective>>. Make sure to set the context of the InvalidDirective error to be the original error. The tests should then check that err.cause() is the expected type.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, this is sorta what i'm thinking as well. been toying with this...

@@ -401,37 +423,49 @@ fn parse_test(line: &str) -> Option<Result<TestCase>> {
fn parse_directive(directive: &str, args: &str, negated: bool) -> Result<TestCase> {
let args = match shlex::split(args) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be ok_or_else

@euclio
Copy link
Contributor

euclio commented Nov 22, 2017

Looks good with comments addressed. Any reason you're preferring ok_or over ok_or_else? I don't think clippy likes that.

@steveklabnik
Copy link
Owner Author

Any reason you're preferring ok_or over ok_or_else? I don't think clippy likes that.

no reason; I'll run clippy too.

now dealing with this fun error:

        thread 'tests::parse_test' panicked at 'unexpected error kind, got InvalidDirective { d: "// @has /test \'[\'" }

invalid JMESPath syntax but expected "InvalidDirective"', tests\source.rs:583:8

hmmmmmmmmmmmmmmmmm

@euclio
Copy link
Contributor

euclio commented Nov 22, 2017

Yeah, I was confused by that too. Does downcasting the cause to jmespath::JmespathError work?

@steveklabnik
Copy link
Owner Author

Yeah, I was confused by that too. Does downcasting the cause to jmespath::JmespathError work?

It doesn't seem to, no matter what I try to cast it to, it doesn't seem to do the right thing. Hrm.

@steveklabnik
Copy link
Owner Author

@euclio so check out this last commit: if we do make it always return InvalidDirective, then there's no reason to assert that type about it. this is now doing something similar to https://boats.gitlab.io/failure/error-errorkind.html; maybe we should do that exactly?

@euclio
Copy link
Contributor

euclio commented Nov 22, 2017

Exactly. Error/ErrorKind could work, but since this is an internal-only error that complexity might not be warranted. We could just make it an enum like here.

@steveklabnik steveklabnik merged commit 7a62956 into master Nov 27, 2017
@steveklabnik
Copy link
Owner Author

Time to :shipit: , if we want to tweak that last error, we can, but I don't think it matters a ton, honestly.

@steveklabnik steveklabnik deleted the failure branch November 27, 2017 18:33
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants