diff --git a/typesense/src/client/mod.rs b/typesense/src/client/mod.rs index 3187a61..9711fd0 100644 --- a/typesense/src/client/mod.rs +++ b/typesense/src/client/mod.rs @@ -124,7 +124,7 @@ mod stopwords; mod synonym_set; mod synonym_sets; -use crate::{Error, traits::Document}; +use crate::{ClientBuilderError, Error, traits::Document}; use alias::Alias; use aliases::Aliases; use analytics::Analytics; @@ -378,13 +378,13 @@ impl Client { #[builder(into, default)] /// The retry policy for transient network errors on a *single* node. retry_policy: ClientRetryPolicy, - ) -> Result { + ) -> Result { let is_nearest_node_set = nearest_node.is_some(); let nodes: Vec<_> = nodes .into_iter() .chain(nearest_node) - .map(|node_config| { + .map(|node_config| -> Result { let builder = match node_config.http_builder { Some(f) => f(reqwest::Client::builder()), None => { @@ -395,13 +395,13 @@ impl Client { } }; + let reqwest_client = builder.build().map_err(ClientBuilderError::HttpClient)?; + #[cfg(target_arch = "wasm32")] - let http_client = builder.build().expect("Failed to build reqwest client"); + let http_client = reqwest_client; #[cfg(not(target_arch = "wasm32"))] - let mw_builder = ReqwestMiddlewareClientBuilder::new( - builder.build().expect("Failed to build reqwest client"), - ); + let mw_builder = ReqwestMiddlewareClientBuilder::new(reqwest_client); #[cfg(not(target_arch = "wasm32"))] let http_client = match retry_policy { @@ -428,16 +428,16 @@ impl Client { ..Default::default() }; - Node { + Ok(Node { config, is_healthy: AtomicBool::new(true), last_accessed: RwLock::new(Instant::now()), - } + }) }) - .collect(); + .collect::, ClientBuilderError>>()?; if nodes.is_empty() { - return Err("Configuration must include at least one node or a nearest_node."); + return Err(ClientBuilderError::NoNodesProvided); } Ok(Self { diff --git a/typesense/src/error.rs b/typesense/src/error.rs index e0f7530..a143cc5 100644 --- a/typesense/src/error.rs +++ b/typesense/src/error.rs @@ -3,6 +3,20 @@ use thiserror::Error; pub use typesense_codegen::apis::{Error as ApiError, ResponseContent}; +/// Errors that can occur when building a Typesense client. +#[derive(Debug, Error)] +pub enum ClientBuilderError { + /// Occurs when no nodes are provided to the Typesense client builder. + /// At least one entry in `nodes` or a `nearest_node` must be provided. + #[error("No nodes provided to the Typesense client builder")] + NoNodesProvided, + + /// Failed to build the underlying HTTP client for a node. + /// This usually indicates an invalid option passed via a custom `http_builder` closure, like a bad TLS certificate. + #[error("Failed to build the underlying HTTP client for a node: {0}")] + HttpClient(reqwest::Error), +} + /// The primary error type for the Typesense client. /// /// This enum encapsulates all possible failures, from network issues to API errors