fix(credential)!: Fallback when an auth method isn't available on the current machine#13558
fix(credential)!: Fallback when an auth method isn't available on the current machine#13558epage wants to merge 10 commits into
Conversation
This isn't really providing much and gets in the way of tweaking the errors.
BREAKING CHANGE: `Error` because an opaque type with the enum broken out into `ErrorKind` - To construct an error from an `ErrorKind`, you can use `Into`. - To wrap an existing error, use `Error::other`
This changes cargo-credential-libsecret to report `UrlNotSupported` errors when `libsecret` can't be loaded. The goal with this change is to make it easier to support a cross-platform, cross-machine config file. Before, someone couldn't enable `libsecret` for the machines that supported it and then fallback to something else on machines that don't. After this change, we should be able to fallback to other providers. To help with debugability, we preserve the "`libsecret` can't be loaded" message by reporting the first "rich" `UrlNotSupported` error message. This is a newly invented construct as part of this PR. This was discussed on [zulip](https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/reg.20auth.20and.20libsecret) and in the cargo team meeting. This is to improve the cross-platform config support in an effort to deprecate having config be unset as part of rust-lang#13343
Like with `libsecret` not being present, process spawn errors can be treated as an indication that that config entry isn't relevant for the current machine and we should try other entries. If there is nothing else to fallback to, we'll still report this error.
|
r? @arlosi |
| let mut child = cmd | ||
| .spawn() | ||
| .context("failed to spawn credential process") | ||
| .map_err(|err| Error::from(err).with_kind(ErrorKind::UrlNotSupported))?; |
There was a problem hiding this comment.
Please add a comment saying why UrlNotSupported is used here. (So that we get the behavior of attempting further providers).
| pasetors = { version = "0.6.8", features = ["v3", "paserk", "std", "serde"] } | ||
| pathdiff = "0.2" | ||
| percent-encoding = "2.3" | ||
| pkg-config = "0.3.30" |
There was a problem hiding this comment.
I don't see this referenced anywhere else in the change. Is it just an unneeded dependency?
| Err::<(), _>(e) | ||
| .with_context(|| { | ||
| format!( | ||
| "credential provider `{}` could not handle the request", |
There was a problem hiding this comment.
Could you please add a UI test so we can see the output when there are multiple failed providers?
| }) | ||
| } | ||
| Err(e) => match e.kind() { | ||
| cargo_credential::ErrorKind::UrlNotSupported => { |
There was a problem hiding this comment.
I'm not sure that the UrlNotSupported error makes sense for "non-fatal" errors. It was intended to indicate that the provider only supports some registry urls (like a provider only for a specific type of registry). It then grew to also be used for the platform-specific providers on the wrong platform - and that still made some sense since they are providers that don't work with any registry.
This use case of non-fatal (continuable) error is much further from that intent. However, I'm not sure what the right solution is.
Here are some other options:
- Make all errors "non-fatal" and continue trying providers for all error types
- Keep the existing behavior, but add an option in the global credential providers config to mark a provider as "optional"
- Add a new error type of
OtherContinuablethat that works as you've implemented it here.
There was a problem hiding this comment.
Talked about this in office hours
Add an alternative to Other that is Backtrack
Backtrackwill need an MSRV note in docs- Maybe add an alias for
Otherthat isCritical- Be careful about forcing MSRV bump
As for whether every error could have a message, this was a bit unclear.
url-not-supported: doesn't need itnot-found: doesn't need itoperation-not-supported: could benefit from it because a login failure on a provider that doesn't support it could give a better message saying why.
In the end, we decided that since the code was written, we should just move forward with a message on each one.
There was a problem hiding this comment.
For message printing:
- On error (everything backtracked):
- Print every provider that backtracked and the message
- On success (a provider matched)
- In extra verbose, print the providers that backtracked and the message
There was a problem hiding this comment.
Since we're doing a breaking change, we should also do #13615
There was a problem hiding this comment.
@arlosi will do that breaking change after this is merged but within the same release
| // Error: The credential could not be found in the provider. | ||
| "kind":"not-found" | ||
| // (Optional) Error message string to be displayed | ||
| "message": "free form string error message", |
There was a problem hiding this comment.
Do these messages from NotFound errors show anywhere?
|
☔ The latest upstream changes (presumably #13577) made this pull request unmergeable. Please resolve the merge conflicts. |
|
☔ The latest upstream changes (possibly 081d7ba) made this pull request unmergeable. Please resolve the merge conflicts. |
0f3b391 to
560efc9
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
My problem was actually #13927 and with that fixed, this isn't needed as much |
What does this PR try to resolve?
This changes cargo-credential-libsecret to report
UrlNotSupportederrors whenlibsecretcan't be loaded. This was also extended totoken-from-stdoutwhen the process can't be spawned.The goal with this change is to make it easier to support a
cross-platform, cross-machine config file.
Before, someone couldn't enable
libsecretfor the machines thatsupported it and then fallback to something else on machines that don't.
After this change, we should be able to fallback to other providers.
To help with debugability, we preserve the "
libsecretcan't be loaded"message by reporting the first "rich"
UrlNotSupportederror message.This is a newly invented construct as part of this PR.
This was discussed on
zulip
and in the cargo team meeting.
This is to improve the cross-platform config support in an effort to
deprecate having config be unset as part of #13343
How should we test and review this PR?
Additional information
Compatibility
cargo-credential'sErrorwent from anenumto an opaquestructwith a separateErrorKindcargo-credentialjson messages can now contain more, optional fieldscargo-credential-libsecretwill no longer hard error iflibsecretcan't be loaded