Skip to content
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

Make ContextCompat consistent and non-ambiguous with WrapErr #150

Merged
merged 8 commits into from
Jun 28, 2024

Conversation

ten3roberts
Copy link
Contributor

@ten3roberts ten3roberts commented Jan 24, 2024

See: #149

Fixes: #149

@LeoniePhiline LeoniePhiline added C-enhancement Category: New feature or request A-eyre Area: eyre subcrate labels Feb 20, 2024
@thenorili thenorili added the breaking change Non-urgent breaking changes, probably delay to the next release label Feb 29, 2024
Copy link
Contributor

@thenorili thenorili left a comment

Choose a reason for hiding this comment

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

This looks like a good change to me, that ambiguity between option and result is detrimental and doesn't fit into our idea of what errors are.

It's a breaking change, so it'll need to wait for a major release.

Could you possibly write up a commit message to match? Other than that it looks fine to go on the experimental branch.

@ten3roberts ten3roberts force-pushed the fix-ambiguous-methods branch 2 times, most recently from 0cc07ae to e3dcdd2 Compare March 12, 2024 21:04
@@ -154,7 +158,7 @@ fn test_option_compat_wrap_err_with() {
}));

use eyre::ContextCompat;
let err = None::<()>.wrap_err_with(|| "oopsie").unwrap_err();
let err = None::<()>.with_context(|| "oopsie").unwrap_err();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This correctly adheres to our model now as you can not "wrap an error" over an option.

You now either use the anyhow compatibility flag, or as the AnyhowCompat suggests the std methods like ok_or_else etc

@ten3roberts
Copy link
Contributor Author

ten3roberts commented Mar 12, 2024

@thenorili I've fixed up the commit message now and cleanup up the PR, let me know what you think 😊

@ten3roberts ten3roberts marked this pull request as ready for review March 15, 2024 12:33
Copy link
Contributor

@thenorili thenorili left a comment

Choose a reason for hiding this comment

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

a couple typos, lgtm

The anyhow compatiblity methods (context and with_context) where
introduced as conditional required methods for the trait WrapErr, as
well as another separate trait ContextCompat, implemented for options
and results.

s/compatiblity/compatibility
s/where/were

Copy link
Contributor

@thenorili thenorili left a comment

Choose a reason for hiding this comment

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

This led to confusion as the two distinct trait
s/trait/traits

Copy link
Contributor

@thenorili thenorili left a comment

Choose a reason for hiding this comment

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

This led to confusion as the two distinct trait had the same methods,
except one was implemented on results, and one of options and results.

suggested:

This led to confusion as the two distinct traits had the same methods,
one was implemented on results and the other on both options and results.


Further, this did not align with our error model, wherein errors are
wrapped with other errors in a chain now that options (which are no
errors and have no message) could be "wrapped"

s/no/not

suggested:

Furthermore, wrapping options doesn't align with our error model where errors are wrapped around other errors; an error wrapping "None" should just be a single error.

1. Remove the conditional trait methods `context` and `with_context`
   from `WrapErr`
2. Remove ambiguity between "wrapping errors" with another, and
   converting a `None` value to an error.

The anyhow compatibility methods (`context` and `with_context`) were
introduced as conditional required methods for the trait `WrapErr`, as
well as another separate trait `ContextCompat`, implemented for options
*and* results.

The latter trait also provided methods `wrap_err` and `wrap_err_with`.
This led to confusion as the two distinct traits had the same methods,
one was implemented on results, and the other on both options and
results.

Furthermore, wrapping options does not align with our error model where
errors are wrapped around other errors; an error wrapping `None` should
just be a single error and should not be wrapped.

See: #149
@ten3roberts
Copy link
Contributor Author

Thanks, will merge the CI fix before to get this to pass

Copy link
Contributor

@LeoniePhiline LeoniePhiline left a comment

Choose a reason for hiding this comment

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

Noticed some inconsistency in trait use placement within tests, where use eyre::ContextCompat was moved upwards from the original use eyre::WrapErr placement, while other use eyre::ContextCompat remain placed right before trait method invocation.

(Let me know if this is too nitpicky <3)

@@ -117,12 +118,13 @@ fn test_context() {
#[cfg(feature = "anyhow")]
#[test]
fn test_with_context() {
use eyre::ContextCompat;
Copy link
Contributor

Choose a reason for hiding this comment

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

As above:

For consistency with the other tests, this use could be moved to after the hook setup, just before using ContextCompat::with_context.

Or the existing uses moved to the start of each test fn as well.

Examples of use right before trait usage:

@@ -100,12 +100,13 @@ fn test_option_ok_or_eyre() {
#[cfg(feature = "anyhow")]
#[test]
fn test_context() {
use eyre::ContextCompat;
Copy link
Contributor

Choose a reason for hiding this comment

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

For consistency with the other tests, this use could be moved to after the hook setup, just before using ContextCompat::with_context.

Or the existing uses moved to the start of each test fn as well.

Examples of use right before trait usage:

This filters out diverging backtraces caused by different before-main
and test calling machinery on windows and linux
Copy link
Contributor

@thenorili thenorili left a comment

Choose a reason for hiding this comment

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

LGTM

eyre/src/lib.rs Outdated
@@ -643,6 +645,7 @@ impl dyn EyreHandler {
}
}

/// Downcast the handler to a contcrete type `T`
Copy link
Contributor

Choose a reason for hiding this comment

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

nit "concrete"

@@ -140,7 +142,7 @@ fn test_option_compat_wrap_err() {
}));

use eyre::ContextCompat;
let err = None::<()>.wrap_err("oopsie").unwrap_err();
let err = None::<()>.context("oopsie").unwrap_err();
Copy link
Contributor

Choose a reason for hiding this comment

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

The encosing test test_option_compat_wrap_err might better be renamed to test_option_compat_context?

Copy link
Contributor

@LeoniePhiline LeoniePhiline Jun 28, 2024

Choose a reason for hiding this comment

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

test_option_compat_context and test_option_compat_with_context already exist and are (now) identical to test_option_compat_wrap_err and test_option_compat_wrap_err_with.

The tests test_option_compat_wrap_err and test_option_compat_wrap_err_with are obsolete and should be deleted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And this is why consistent naming is so good, cause now that yields a duplicate definition error.

Thanks a lot for your suggestions 😊

@@ -155,7 +157,7 @@ fn test_option_compat_wrap_err_with() {
}));

use eyre::ContextCompat;
let err = None::<()>.wrap_err_with(|| "oopsie").unwrap_err();
let err = None::<()>.with_context(|| "oopsie").unwrap_err();
Copy link
Contributor

Choose a reason for hiding this comment

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

The encosing test test_option_compat_wrap_err_with might better be renamed to test_option_compat_with_context?

@LeoniePhiline
Copy link
Contributor

#179 should fix my comments.

@ten3roberts ten3roberts merged commit 9498677 into master Jun 28, 2024
29 checks passed
@ten3roberts ten3roberts deleted the fix-ambiguous-methods branch June 28, 2024 15:46
@SuperFluffy
Copy link

This caught me today. I would love to see this released soon. 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-eyre Area: eyre subcrate breaking change Non-urgent breaking changes, probably delay to the next release C-enhancement Category: New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ BREAKING ] ContextCompat contains identically named methods to WrapErr which can be confusing and a footgun
4 participants