use super::Client;
use crate::client;
use salesforce_core_restapi::types::SearchResponse;
use salesforce_core_restapi::{Client as GeneratedClient, Error as GeneratedError};
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[error("Authentication error: {source}")]
Auth {
#[source]
source: client::Error,
},
#[error("Search API error: {source}")]
SearchApi {
#[source]
source: GeneratedError<salesforce_core_restapi::types::ErrorResponse>,
},
#[error("Communication error: {source}")]
Communication {
#[source]
source: reqwest::Error,
},
}
impl Client {
pub async fn search(&self, sosl_query: impl AsRef<str>) -> Result<SearchResponse, Error> {
let sosl_query = sosl_query.as_ref();
let http_client = self.get_http_client().await.map_err(|e| match e {
crate::http::Error::Auth { source } => Error::Auth { source },
crate::http::Error::InvalidHeader | crate::http::Error::Lock => Error::Auth {
source: client::Error::LockError,
},
crate::http::Error::Build { source } => Error::Communication { source },
})?;
let base_url = self.base_url().map_err(|source| Error::Auth { source })?;
let client = GeneratedClient::new_with_client(&base_url, http_client);
let response = client
.search(sosl_query)
.await
.map_err(|source| Error::SearchApi { source })?;
Ok(response.into_inner())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_source_chain_preserved() {
let auth_error = client::Error::LockError;
let error = Error::Auth { source: auth_error };
assert!(std::error::Error::source(&error).is_some());
}
#[tokio::test]
async fn test_reqwest_error_conversion() {
let reqwest_error = reqwest::Client::new()
.get("http://invalid-url-that-does-not-exist.test")
.send()
.await
.unwrap_err();
let error = Error::Communication {
source: reqwest_error,
};
assert!(matches!(error, Error::Communication { .. }));
assert!(std::error::Error::source(&error).is_some());
}
}