@@ -47,7 +47,7 @@ use uv_warnings::warn_user_once;
4747
4848use crate :: linehaul:: LineHaul ;
4949use crate :: middleware:: OfflineMiddleware ;
50- use crate :: tls:: { Certificates , read_identity} ;
50+ use crate :: tls:: { Certificates , TlsConfigurationError , read_identity} ;
5151use crate :: { Connectivity , WrappedReqwestError } ;
5252
5353pub const DEFAULT_RETRIES : u32 = 3 ;
@@ -71,6 +71,44 @@ pub const DEFAULT_CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
7171/// timeout on the entire upload.
7272pub const DEFAULT_READ_TIMEOUT_UPLOAD : Duration = Duration :: from_mins ( 15 ) ;
7373
74+ #[ derive( Debug ) ]
75+ pub struct ClientBuildError ( ClientBuildErrorKind ) ;
76+
77+ #[ derive( Debug , Error ) ]
78+ enum ClientBuildErrorKind {
79+ #[ error( transparent) ]
80+ Reqwest ( reqwest:: Error ) ,
81+ #[ error( transparent) ]
82+ TlsConfiguration ( TlsConfigurationError ) ,
83+ }
84+
85+ impl std:: fmt:: Display for ClientBuildError {
86+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
87+ f. write_str ( "failed to build HTTP client" )
88+ }
89+ }
90+
91+ impl std:: error:: Error for ClientBuildError {
92+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
93+ match & self . 0 {
94+ ClientBuildErrorKind :: Reqwest ( error) => Some ( error) ,
95+ ClientBuildErrorKind :: TlsConfiguration ( error) => Some ( error) ,
96+ }
97+ }
98+ }
99+
100+ impl From < reqwest:: Error > for ClientBuildError {
101+ fn from ( error : reqwest:: Error ) -> Self {
102+ Self ( ClientBuildErrorKind :: Reqwest ( error) )
103+ }
104+ }
105+
106+ impl From < TlsConfigurationError > for ClientBuildError {
107+ fn from ( error : TlsConfigurationError ) -> Self {
108+ Self ( ClientBuildErrorKind :: TlsConfiguration ( error) )
109+ }
110+ }
111+
74112/// Selectively skip parts or the entire auth middleware.
75113#[ derive( Debug , Clone , Copy , Default ) ]
76114pub enum AuthIntegration {
@@ -380,7 +418,7 @@ impl<'a> BaseClientBuilder<'a> {
380418 retry_policy ( self . retries , self . no_retry_delay )
381419 }
382420
383- pub fn build ( & self ) -> reqwest :: Result < BaseClient > {
421+ pub fn build ( & self ) -> Result < BaseClient , ClientBuildError > {
384422 if let Some ( name) = self . client_name {
385423 debug ! (
386424 "Using request connect timeout of {}s and read timeout of {}s for {} client" ,
@@ -464,7 +502,7 @@ impl<'a> BaseClientBuilder<'a> {
464502 & self ,
465503 read_timeout : Duration ,
466504 connect_timeout : Duration ,
467- ) -> reqwest :: Result < ( Client , Client ) > {
505+ ) -> Result < ( Client , Client ) , ClientBuildError > {
468506 // Create user agent.
469507 let mut user_agent_string = format ! ( "uv/{}" , version( ) ) ;
470508
@@ -475,7 +513,7 @@ impl<'a> BaseClientBuilder<'a> {
475513 }
476514
477515 // Load custom CA certificates from `SSL_CERT_FILE` and `SSL_CERT_DIR`.
478- let custom_certs = Certificates :: from_env ( ) . map ( |certs| certs. to_reqwest_certs ( ) ) ;
516+ let custom_certs = Certificates :: from_env ( ) ? . map ( |certs| certs. to_reqwest_certs ( ) ) ;
479517
480518 // Create a secure client that validates certificates.
481519 let raw_client = self . create_client (
@@ -508,7 +546,7 @@ impl<'a> BaseClientBuilder<'a> {
508546 custom_certs : Option < Vec < Certificate > > ,
509547 security : Security ,
510548 redirect_policy : RedirectPolicy ,
511- ) -> reqwest :: Result < Client > {
549+ ) -> Result < Client , ClientBuildError > {
512550 // Configure the builder.
513551 let client_builder = ClientBuilder :: new ( )
514552 . http1_title_case_headers ( )
@@ -574,7 +612,7 @@ impl<'a> BaseClientBuilder<'a> {
574612 client_builder = client_builder. proxy ( proxy) ;
575613 }
576614
577- client_builder. build ( )
615+ client_builder. build ( ) . map_err ( Into :: into )
578616 }
579617
580618 fn apply_middleware ( & self , client : Client ) -> ClientWithMiddleware {
0 commit comments