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

Prefer partial success to failure #126

Merged
merged 3 commits into from
Aug 28, 2024
Merged

Prefer partial success to failure #126

merged 3 commits into from
Aug 28, 2024

Conversation

ctz
Copy link
Member

@ctz ctz commented Aug 20, 2024

fixes #124

Draft release notes:

```shell
$ SSL_CERT_FILE="notexist" target/debug/examples/google
thread 'main' panicked at examples/google.rs:7:58:
could not load platform certs: Custom { kind: NotFound, error: "could not load certs from dir notexist: No such file or directory (os error 2)" }
```

Note "from dir notexist".  In this case `path.is_file()` is false
(because it doesn't exist) but that doesn't imply it was being
read as a directory.
If we read some certs from a file, but fail to read some from
a directory (or vv.) then return what we have.

This is good because it restores the crate's previous behaviour.
It also matches what (for example) golang crypto.x509 does.

This is bad because it hides a failure, which would be confusing
if a user relied on reading from _both_ a file and directory at
the same time.  Would someone do that?  The follow commit steps
towards ameliorating this, slightly.
Copy link
Member

@djc djc left a comment

Choose a reason for hiding this comment

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

If we're going to do this, should we also try to be more forgiving inside load_certs_from_dir()? What about the various implementations of load_certs()? I think both could skip over some error cases.

Are we trying to maintain backwards compatibility or making the library entirely best effort? And if it's the latter, wouldn't it still be better to make the API explicit about this by returning retrieved certificates and errors so that the application can decide how strict it wants to be?

}

// promote first error if we have no certs to return
if let (Some(error), []) = (first_error, certs.as_slice()) {
Copy link
Member

Choose a reason for hiding this comment

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

Just to call this out: is the 0 vs 1 boundary the right one? It is different from the previous approach -- it would be "more" backwards-compatible if we just swallowed the error from load_pem_certs_from_dir(), I suppose?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not quite grasping what this comment is saying, could your reword? Is it whether we return the first or last error? Or about the preexisting behaviour where the crate can return Ok([])?

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
Copy link
Member

@cpu cpu left a comment

Choose a reason for hiding this comment

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

Thanks, this seems reasonable to me.

@cpu
Copy link
Member

cpu commented Aug 26, 2024

If we're going to do this, should we also try to be more forgiving inside load_certs_from_dir()? What about the various implementations of load_certs()? I think both could skip over some error cases.

I'm not sure I follow what you're thinking here, the only public API surface is load_native_certs(), which calls the crate internal load() being updated in this changeset. I don't think there's anywhere else that needs to be updated to skip error cases 🤔

@djc djc mentioned this pull request Aug 26, 2024
@ctz
Copy link
Member Author

ctz commented Aug 28, 2024

So if we follow #128 (comment), which I think we should, I am minded to remove the tracing stuff here (the feature, dependency, and calls), on the basis that:

  • even though the new API is a breaking change, adding and then immediately removing a feature & dependency seems a bit silly
  • the new API fixes this in a more convincing way, so the half-assed way of logging swallowed errors is a cul-de-sac

@cpu
Copy link
Member

cpu commented Aug 28, 2024

So if we follow #128 (comment), which I think we should, I am minded to remove the tracing stuff here (the feature, dependency, and calls)

That sounds sensible to me 👍

@djc
Copy link
Member

djc commented Aug 28, 2024

Yup, makes sense.

@ctz
Copy link
Member Author

ctz commented Aug 28, 2024

Dropped that commit.

Copy link
Member

@djc djc left a comment

Choose a reason for hiding this comment

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

Want to draft some release notes?

@ctz
Copy link
Member Author

ctz commented Aug 28, 2024

Added up top, please review.

@ctz ctz added this pull request to the merge queue Aug 28, 2024
@djc
Copy link
Member

djc commented Aug 28, 2024

Looks great to me!

Merged via the queue into main with commit 0d6fb06 Aug 28, 2024
28 checks passed
@ctz ctz deleted the jbp-best-effort-errors branch August 28, 2024 14:10
@cpu
Copy link
Member

cpu commented Aug 28, 2024

LGTM too, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

”Permission denied“ since v0.7.1
3 participants