mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-02 12:59:45 +00:00
Recommend --native-tls on SSL errors (#10605)
## Summary Closes https://github.com/astral-sh/uv/issues/10574. ## Test Plan ``` ❯ SSL_CERT_FILE=a cargo run pip install flask -n Compiling uv v0.5.18 (/Users/crmarsh/workspace/uv/crates/uv) Finished `dev` profile [unoptimized + debuginfo] target(s) in 8.33s Running `target/debug/uv pip install flask -n` ⠦ Resolving dependencies... × Failed to fetch: `https://pypi.org/simple/flask/` ├─▶ Request failed after 3 retries ├─▶ error sending request for url (https://pypi.org/simple/flask/) ├─▶ client error (Connect) ╰─▶ invalid peer certificate: UnknownIssuer help: Consider enabling native TLS support via the `--native-tls` command-line flag ```
This commit is contained in:
parent
e1e9b0447c
commit
325b060829
14 changed files with 124 additions and 38 deletions
|
|
@ -51,6 +51,11 @@ impl Error {
|
||||||
matches!(err.kind(), std::io::ErrorKind::NotFound)
|
matches!(err.kind(), std::io::ErrorKind::NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the error is due to an SSL error.
|
||||||
|
pub fn is_ssl(&self) -> bool {
|
||||||
|
matches!(&*self.kind, ErrorKind::WrappedReqwestError(.., err) if err.is_ssl())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the error is due to the server not supporting HTTP range requests.
|
/// Returns `true` if the error is due to the server not supporting HTTP range requests.
|
||||||
pub fn is_http_range_requests_unsupported(&self) -> bool {
|
pub fn is_http_range_requests_unsupported(&self) -> bool {
|
||||||
match &*self.kind {
|
match &*self.kind {
|
||||||
|
|
@ -260,13 +265,9 @@ impl ErrorKind {
|
||||||
pub struct WrappedReqwestError(reqwest_middleware::Error);
|
pub struct WrappedReqwestError(reqwest_middleware::Error);
|
||||||
|
|
||||||
impl WrappedReqwestError {
|
impl WrappedReqwestError {
|
||||||
/// Check if the error chain contains a reqwest error that looks like this:
|
/// Return the inner [`reqwest::Error`] from the error chain, if it exists.
|
||||||
/// * error sending request for url (...)
|
fn inner(&self) -> Option<&reqwest::Error> {
|
||||||
/// * client error (Connect)
|
match &self.0 {
|
||||||
/// * dns error: failed to lookup address information: Name or service not known
|
|
||||||
/// * failed to lookup address information: Name or service not known
|
|
||||||
fn is_likely_offline(&self) -> bool {
|
|
||||||
let reqwest_err = match &self.0 {
|
|
||||||
reqwest_middleware::Error::Reqwest(err) => Some(err),
|
reqwest_middleware::Error::Reqwest(err) => Some(err),
|
||||||
reqwest_middleware::Error::Middleware(err) => err.chain().find_map(|err| {
|
reqwest_middleware::Error::Middleware(err) => err.chain().find_map(|err| {
|
||||||
if let Some(err) = err.downcast_ref::<reqwest::Error>() {
|
if let Some(err) = err.downcast_ref::<reqwest::Error>() {
|
||||||
|
|
@ -279,9 +280,16 @@ impl WrappedReqwestError {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(reqwest_err) = reqwest_err {
|
/// Check if the error chain contains a `reqwest` error that looks like this:
|
||||||
|
/// * error sending request for url (...)
|
||||||
|
/// * client error (Connect)
|
||||||
|
/// * dns error: failed to lookup address information: Name or service not known
|
||||||
|
/// * failed to lookup address information: Name or service not known
|
||||||
|
fn is_likely_offline(&self) -> bool {
|
||||||
|
if let Some(reqwest_err) = self.inner() {
|
||||||
if !reqwest_err.is_connect() {
|
if !reqwest_err.is_connect() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -297,6 +305,26 @@ impl WrappedReqwestError {
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the error chain contains a `reqwest` error that looks like this:
|
||||||
|
/// * invalid peer certificate: `UnknownIssuer`
|
||||||
|
fn is_ssl(&self) -> bool {
|
||||||
|
if let Some(reqwest_err) = self.inner() {
|
||||||
|
if !reqwest_err.is_connect() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Self is "error sending request for url", the first source is "error trying to connect",
|
||||||
|
// the second source is "dns error". We have to check for the string because hyper errors
|
||||||
|
// are opaque.
|
||||||
|
if std::error::Error::source(&reqwest_err)
|
||||||
|
.and_then(|err| err.source())
|
||||||
|
.is_some_and(|err| err.to_string().starts_with("invalid peer certificate: "))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<reqwest::Error> for WrappedReqwestError {
|
impl From<reqwest::Error> for WrappedReqwestError {
|
||||||
|
|
|
||||||
|
|
@ -34,26 +34,37 @@ static SUGGESTIONS: LazyLock<FxHashMap<PackageName, PackageName>> = LazyLock::ne
|
||||||
pub(crate) struct OperationDiagnostic {
|
pub(crate) struct OperationDiagnostic {
|
||||||
/// The hint to display to the user upon resolution failure.
|
/// The hint to display to the user upon resolution failure.
|
||||||
pub(crate) hint: Option<String>,
|
pub(crate) hint: Option<String>,
|
||||||
|
/// Whether native TLS is enabled.
|
||||||
|
pub(crate) native_tls: bool,
|
||||||
/// The context to display to the user upon resolution failure.
|
/// The context to display to the user upon resolution failure.
|
||||||
pub(crate) context: Option<&'static str>,
|
pub(crate) context: Option<&'static str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OperationDiagnostic {
|
impl OperationDiagnostic {
|
||||||
|
/// Create an [`OperationDiagnostic`] with the given native TLS setting.
|
||||||
|
#[must_use]
|
||||||
|
pub(crate) fn native_tls(native_tls: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
native_tls,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the hint to display to the user upon resolution failure.
|
/// Set the hint to display to the user upon resolution failure.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn with_hint(hint: String) -> Self {
|
pub(crate) fn with_hint(self, hint: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
hint: Some(hint),
|
hint: Some(hint),
|
||||||
..Default::default()
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the context to display to the user upon resolution failure.
|
/// Set the context to display to the user upon resolution failure.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn with_context(context: &'static str) -> Self {
|
pub(crate) fn with_context(self, context: &'static str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
context: Some(context),
|
context: Some(context),
|
||||||
..Default::default()
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,6 +117,12 @@ impl OperationDiagnostic {
|
||||||
Some(pip::operations::Error::Requirements(err))
|
Some(pip::operations::Error::Requirements(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pip::operations::Error::Resolve(uv_resolver::ResolveError::Client(err))
|
||||||
|
if !self.native_tls && err.is_ssl() =>
|
||||||
|
{
|
||||||
|
native_tls_hint(err);
|
||||||
|
None
|
||||||
|
}
|
||||||
err => Some(err),
|
err => Some(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -236,6 +253,41 @@ pub(crate) fn no_solution_hint(err: uv_resolver::NoSolutionError, help: String)
|
||||||
anstream::eprint!("{report:?}");
|
anstream::eprint!("{report:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Render a [`uv_resolver::NoSolutionError`] with a help message.
|
||||||
|
pub(crate) fn native_tls_hint(err: uv_client::Error) {
|
||||||
|
#[derive(Debug, miette::Diagnostic)]
|
||||||
|
#[diagnostic()]
|
||||||
|
struct Error {
|
||||||
|
/// The underlying error.
|
||||||
|
err: uv_client::Error,
|
||||||
|
|
||||||
|
/// The help message to display.
|
||||||
|
#[help]
|
||||||
|
help: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
self.err.source()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let report = miette::Report::new(Error {
|
||||||
|
err,
|
||||||
|
help: format!(
|
||||||
|
"Consider enabling use of system TLS certificates with the `{}` command-line flag",
|
||||||
|
"--native-tls".green()
|
||||||
|
),
|
||||||
|
});
|
||||||
|
anstream::eprint!("{report:?}");
|
||||||
|
}
|
||||||
|
|
||||||
/// Format a [`DerivationChain`] as a human-readable error message.
|
/// Format a [`DerivationChain`] as a human-readable error message.
|
||||||
fn format_chain(name: &PackageName, version: Option<&Version>, chain: &DerivationChain) -> String {
|
fn format_chain(name: &PackageName, version: Option<&Version>, chain: &DerivationChain) -> String {
|
||||||
/// Format a step in the [`DerivationChain`] as a human-readable error message.
|
/// Format a step in the [`DerivationChain`] as a human-readable error message.
|
||||||
|
|
|
||||||
|
|
@ -401,7 +401,7 @@ pub(crate) async fn pip_compile(
|
||||||
{
|
{
|
||||||
Ok(resolution) => resolution,
|
Ok(resolution) => resolution,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,7 @@ pub(crate) async fn pip_install(
|
||||||
{
|
{
|
||||||
Ok(graph) => Resolution::from(graph),
|
Ok(graph) => Resolution::from(graph),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -462,7 +462,7 @@ pub(crate) async fn pip_install(
|
||||||
{
|
{
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ pub(crate) async fn pip_sync(
|
||||||
{
|
{
|
||||||
Ok(resolution) => Resolution::from(resolution),
|
Ok(resolution) => Resolution::from(resolution),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -407,7 +407,7 @@ pub(crate) async fn pip_sync(
|
||||||
{
|
{
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -632,7 +632,7 @@ pub(crate) async fn add(
|
||||||
let _ = snapshot.revert();
|
let _ = snapshot.revert();
|
||||||
}
|
}
|
||||||
match err {
|
match err {
|
||||||
ProjectError::Operation(err) => diagnostics::OperationDiagnostic::with_hint(format!("If you want to add the package regardless of the failed resolution, provide the `{}` flag to skip locking and syncing.", "--frozen".green()))
|
ProjectError::Operation(err) => diagnostics::OperationDiagnostic::native_tls(native_tls).with_hint(format!("If you want to add the package regardless of the failed resolution, provide the `{}` flag to skip locking and syncing.", "--frozen".green()))
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into())),
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into())),
|
||||||
err => Err(err.into()),
|
err => Err(err.into()),
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ pub(crate) async fn export(
|
||||||
{
|
{
|
||||||
Ok(result) => result.into_lock(),
|
Ok(result) => result.into_lock(),
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,9 +193,11 @@ pub(crate) async fn lock(
|
||||||
|
|
||||||
Ok(ExitStatus::Success)
|
Ok(ExitStatus::Success)
|
||||||
}
|
}
|
||||||
Err(ProjectError::Operation(err)) => diagnostics::OperationDiagnostic::default()
|
Err(ProjectError::Operation(err)) => {
|
||||||
.report(err)
|
diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into())),
|
.report(err)
|
||||||
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
|
}
|
||||||
Err(err) => Err(err.into()),
|
Err(err) => Err(err.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ pub(crate) async fn remove(
|
||||||
{
|
{
|
||||||
Ok(result) => result.into_lock(),
|
Ok(result) => result.into_lock(),
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -349,7 +349,7 @@ pub(crate) async fn remove(
|
||||||
{
|
{
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,8 @@ pub(crate) async fn run(
|
||||||
let environment = match result {
|
let environment = match result {
|
||||||
Ok(resolution) => resolution,
|
Ok(resolution) => resolution,
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::with_context("script")
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
|
.with_context("script")
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -415,7 +416,8 @@ pub(crate) async fn run(
|
||||||
let environment = match result {
|
let environment = match result {
|
||||||
Ok(resolution) => resolution,
|
Ok(resolution) => resolution,
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::with_context("script")
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
|
.with_context("script")
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -738,7 +740,7 @@ pub(crate) async fn run(
|
||||||
{
|
{
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -819,7 +821,7 @@ pub(crate) async fn run(
|
||||||
{
|
{
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -972,7 +974,8 @@ pub(crate) async fn run(
|
||||||
let environment = match result {
|
let environment = match result {
|
||||||
Ok(resolution) => resolution,
|
Ok(resolution) => resolution,
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::with_context("`--with`")
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
|
.with_context("`--with`")
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ pub(crate) async fn sync(
|
||||||
{
|
{
|
||||||
Ok(result) => result.into_lock(),
|
Ok(result) => result.into_lock(),
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +236,7 @@ pub(crate) async fn sync(
|
||||||
{
|
{
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ pub(crate) async fn tree(
|
||||||
{
|
{
|
||||||
Ok(result) => result.into_lock(),
|
Ok(result) => result.into_lock(),
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ pub(crate) async fn install(
|
||||||
{
|
{
|
||||||
Ok(update) => update.into_environment(),
|
Ok(update) => update.into_environment(),
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
@ -491,7 +491,7 @@ pub(crate) async fn install(
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
.flatten() else {
|
.flatten() else {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
|
||||||
};
|
};
|
||||||
|
|
@ -520,7 +520,7 @@ pub(crate) async fn install(
|
||||||
{
|
{
|
||||||
Ok(resolution) => resolution,
|
Ok(resolution) => resolution,
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
|
||||||
}
|
}
|
||||||
|
|
@ -563,7 +563,7 @@ pub(crate) async fn install(
|
||||||
}) {
|
}) {
|
||||||
Ok(environment) => environment,
|
Ok(environment) => environment,
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::default()
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,8 @@ pub(crate) async fn run(
|
||||||
let (from, environment) = match result {
|
let (from, environment) = match result {
|
||||||
Ok(resolution) => resolution,
|
Ok(resolution) => resolution,
|
||||||
Err(ProjectError::Operation(err)) => {
|
Err(ProjectError::Operation(err)) => {
|
||||||
return diagnostics::OperationDiagnostic::with_context("tool")
|
return diagnostics::OperationDiagnostic::native_tls(native_tls)
|
||||||
|
.with_context("tool")
|
||||||
.report(err)
|
.report(err)
|
||||||
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue