Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions bitwarden_license/bitwarden-sm/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use bitwarden_api_api::apis::Error as ApiApisError;
use thiserror::Error;
use tracing::debug;
use validator::ValidationErrors;
Expand Down Expand Up @@ -81,9 +80,3 @@ impl From<ValidationErrors> for SecretsManagerError {
SecretsManagerError::Validation(e.into())
}
}

impl<T> From<ApiApisError<T>> for SecretsManagerError {
fn from(e: bitwarden_api_api::apis::Error<T>) -> Self {
SecretsManagerError::Api(e.into())
}
}
26 changes: 10 additions & 16 deletions crates/bitwarden-api-base/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Error types for API operations.

use std::{convert::Infallible, error, fmt, marker::PhantomData};
use std::{error, fmt};

use serde::{Deserialize, Serialize};

Expand All @@ -18,7 +18,7 @@ pub struct ResponseContent {
/// Errors that can occur during API operations.
#[derive(Debug)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
pub enum Error<T = ()> {
pub enum Error {
/// Error from the reqwest HTTP client.
Reqwest(reqwest::Error),
/// Error from the reqwest middleware.
Expand All @@ -29,64 +29,58 @@ pub enum Error<T = ()> {
Io(std::io::Error),
/// API returned an error response.
Response(ResponseContent),

/// Phantom variant to keep the unused `T` parameter alive without affecting downstream
/// `impl<T> From<Error<T>> for FooError` impls. Uninhabited via [`Infallible`].
#[doc(hidden)]
_Phantom(PhantomData<T>, Infallible),
}

impl<T> fmt::Display for Error<T> {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (module, e) = match self {
Error::Reqwest(e) => ("reqwest", e.to_string()),
Error::ReqwestMiddleware(e) => ("reqwest-middleware", e.to_string()),
Error::Serde(e) => ("serde", e.to_string()),
Error::Io(e) => ("IO", e.to_string()),
Error::Response(e) => ("response", format!("status code {}", e.status)),
Error::_Phantom(_, _) => unreachable!(),
};
write!(f, "error in {}: {}", module, e)
}
}

impl<T: fmt::Debug> error::Error for Error<T> {
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(match self {
Error::Reqwest(e) => e,
Error::ReqwestMiddleware(e) => e,
Error::Serde(e) => e,
Error::Io(e) => e,
Error::Response(_) | Error::_Phantom(_, _) => return None,
Error::Response(_) => return None,
})
}
}

impl<T> From<reqwest::Error> for Error<T> {
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Self {
Error::Reqwest(e)
}
}

impl<T> From<reqwest_middleware::Error> for Error<T> {
impl From<reqwest_middleware::Error> for Error {
fn from(e: reqwest_middleware::Error) -> Self {
Error::ReqwestMiddleware(e)
}
}

impl<T> From<serde_json::Error> for Error<T> {
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
Error::Serde(e)
}
}

impl<T> From<std::io::Error> for Error<T> {
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
Error::Io(e)
}
}

impl<T> From<ResponseContent> for Error<T> {
impl From<ResponseContent> for Error {
fn from(value: ResponseContent) -> Self {
Self::Response(value)
}
Expand Down
12 changes: 6 additions & 6 deletions crates/bitwarden-api-base/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ fn content_type(response: &reqwest::Response) -> ContentType {
/// used with. This function contains the non-generic logic for processing the response so that it
/// doesn't get duplicated.
#[inline(never)]
async fn process_with_json_response_internal<E>(
async fn process_with_json_response_internal(
request: reqwest_middleware::RequestBuilder,
) -> Result<String, crate::Error<E>> {
) -> Result<String, crate::Error> {
let response = request.send().await?;
let status = response.status();
let content_type = content_type(&response);
Expand All @@ -41,19 +41,19 @@ async fn process_with_json_response_internal<E>(
}

/// Sends and processes a request expecting a JSON response, deserializing it into the type `T`.
pub async fn process_with_json_response<T: DeserializeOwned, E>(
pub async fn process_with_json_response<T: DeserializeOwned>(
request: reqwest_middleware::RequestBuilder,
) -> Result<T, crate::Error<E>> {
) -> Result<T, crate::Error> {
process_with_json_response_internal(request)
.await
.and_then(|content| serde_json::from_str(&content).map_err(Into::into))
}

/// Sends and processes a request expecting an empty response, returning `Ok(())` when successful.
#[inline(never)]
pub async fn process_with_empty_response<E>(
pub async fn process_with_empty_response(
request: reqwest_middleware::RequestBuilder,
) -> Result<(), crate::Error<E>> {
) -> Result<(), crate::Error> {
let response = request.send().await?;
let status = response.status();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ impl LoginClient {
.identity_client
.accounts_api()
.post_password_prelogin(Some(request_model))
.await
.map_err(ApiError::from)?;
.await?;

Ok(PasswordPreloginResponse::try_from(response)?)
}
Expand Down
8 changes: 3 additions & 5 deletions crates/bitwarden-core/src/auth/login/auth_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use uuid::Uuid;

use super::LoginError;
use crate::{
ApiError, Client,
Client,
auth::{
api::{request::AuthRequestTokenRequest, response::IdentityTokenResponse},
auth_request::new_auth_request,
Expand Down Expand Up @@ -49,8 +49,7 @@ pub(crate) async fn send_new_auth_request(
.api_client
.auth_requests_api()
.post(Some(req))
.await
.map_err(ApiError::from)?;
.await?;

Ok(NewAuthRequestResponse {
fingerprint: auth.fingerprint,
Expand All @@ -71,8 +70,7 @@ pub(crate) async fn complete_auth_request(
.api_client
.auth_requests_api()
.get_response(auth_req.auth_request_id, Some(&auth_req.access_code))
.await
.map_err(ApiError::from)?;
.await?;

let approved = res.request_approved.unwrap_or(false);

Expand Down
3 changes: 1 addition & 2 deletions crates/bitwarden-core/src/auth/login/prelogin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ pub(crate) async fn prelogin(client: &Client, email: String) -> Result<Kdf, Prel
.identity_client
.accounts_api()
.post_password_prelogin(Some(request_model))
.await
.map_err(ApiError::from)?;
.await?;

Ok(parse_prelogin(result)?)
}
Expand Down
3 changes: 1 addition & 2 deletions crates/bitwarden-core/src/auth/login/two_factor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ pub(crate) async fn send_two_factor_email(
auth_request_id: None,
sso_email2_fa_session_token: None,
}))
.await
.map_err(ApiError::from)?;
.await?;

Ok(())
}
Expand Down
41 changes: 1 addition & 40 deletions crates/bitwarden-core/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,10 @@
//! Errors that can occur when using this SDK

use std::fmt::Debug;

use bitwarden_api_base::{Error as BaseApiError, ResponseContent};
pub use bitwarden_api_base::Error as ApiError;
#[cfg(feature = "internal")]
use bitwarden_error::bitwarden_error;
use thiserror::Error;

/// Errors from performing network requests.
#[allow(missing_docs)]
#[derive(Debug, Error)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
pub enum ApiError {
#[error(transparent)]
Reqwest(#[from] reqwest::Error),
#[error(transparent)]
ReqwestMiddleware(#[from] reqwest_middleware::Error),
#[error(transparent)]
Serde(#[from] serde_json::Error),
#[error(transparent)]
Io(#[from] std::io::Error),

#[error("Received error message from server: [{}] {}", _0.status, _0.message)]
Response(ResponseContent),
}

impl<T> From<BaseApiError<T>> for ApiError {
fn from(e: BaseApiError<T>) -> Self {
match e {
BaseApiError::Reqwest(e) => Self::Reqwest(e),
BaseApiError::ReqwestMiddleware(e) => Self::ReqwestMiddleware(e),
BaseApiError::Response(e) => Self::Response(e),
BaseApiError::Serde(e) => Self::Serde(e),
BaseApiError::Io(e) => Self::Io(e),
BaseApiError::_Phantom(_, _) => unreachable!(),
}
}
}

impl From<ResponseContent> for ApiError {
fn from(value: ResponseContent) -> Self {
Self::Response(value)
}
}

/// Client is not authenticated or the session has expired.
#[derive(Debug, Error)]
#[error("The client is not authenticated or the session has expired")]
Expand Down
3 changes: 1 addition & 2 deletions crates/bitwarden-core/src/platform/get_user_api_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ pub(crate) async fn get_user_api_key(
.api_client
.accounts_api()
.api_key(Some(request))
.await
.map_err(ApiError::from)?;
.await?;
UserApiKeyResponse::process_response(response)
}

Expand Down
12 changes: 4 additions & 8 deletions crates/bitwarden-send/src/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ async fn access_send_v1(
let resp = api_client
.sends_api()
.access(send_id, Some(models::SendAccessRequestModel { password }))
.await
.map_err(ApiError::from)?;
.await?;
Ok(resp.try_into()?)
}

Expand All @@ -121,8 +120,7 @@ async fn access_send(
let resp = api_client
.sends_api()
.access_using_auth(access_token)
.await
.map_err(ApiError::from)?;
.await?;
Ok(resp.try_into()?)
}

Expand All @@ -139,8 +137,7 @@ async fn get_file_download_data_v1(
file_id,
Some(models::SendAccessRequestModel { password }),
)
.await
.map_err(ApiError::from)?;
.await?;
Ok(resp.into())
}

Expand All @@ -152,8 +149,7 @@ async fn get_file_download_data(
let resp = api_client
.sends_api()
.get_send_file_download_data_using_auth(file_id, access_token)
.await
.map_err(ApiError::from)?;
.await?;
Ok(resp.into())
}

Expand Down
6 changes: 1 addition & 5 deletions crates/bitwarden-send/src/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,7 @@ async fn create_send<R: Repository<Send> + ?Sized>(

let send_request = key_store.encrypt(request)?;

let resp = api_client
.sends_api()
.post(Some(send_request))
.await
.map_err(ApiError::from)?;
let resp = api_client.sends_api().post(Some(send_request)).await?;

let send: Send = resp.try_into()?;

Expand Down
10 changes: 3 additions & 7 deletions crates/bitwarden-send/src/create_file_send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ impl SendClient {
.api_client
.sends_api()
.post_file(Some(send_request))
.await
.map_err(ApiError::from)?;
.await?;

let url = require!(resp.url);
let file_upload_type: FileUploadType = require!(resp.file_upload_type).try_into()?;
Expand Down Expand Up @@ -200,9 +199,7 @@ impl SendClient {
.with_extension(AuthRequired::Bearer)
.multipart(form);

bitwarden_api_base::process_with_empty_response(req_builder)
.await
.map_err(|e: bitwarden_api_api::apis::Error<()>| ApiError::from(e))?;
bitwarden_api_base::process_with_empty_response(req_builder).await?;

Ok(())
}
Expand All @@ -221,8 +218,7 @@ impl SendClient {
.api_client
.sends_api()
.renew_file_upload(&send_id.to_string(), &file_id)
.await
.map_err(ApiError::from)?;
.await?;

Ok(require!(resp.url))
}
Expand Down
6 changes: 1 addition & 5 deletions crates/bitwarden-send/src/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ async fn delete_send<R: Repository<Send> + ?Sized>(
repository: &R,
send_id: SendId,
) -> Result<(), DeleteSendError> {
api_client
.sends_api()
.delete(&send_id.to_string())
.await
.map_err(ApiError::from)?;
api_client.sends_api().delete(&send_id.to_string()).await?;

repository.remove(send_id).await?;

Expand Down
6 changes: 1 addition & 5 deletions crates/bitwarden-send/src/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,7 @@ async fn edit_send<R: Repository<Send> + ?Sized>(

let send_request = key_store.encrypt(request_with_key)?;

let resp = api_client
.sends_api()
.put(&id, Some(send_request))
.await
.map_err(ApiError::from)?;
let resp = api_client.sends_api().put(&id, Some(send_request)).await?;

let send: Send = resp.try_into()?;

Expand Down
3 changes: 1 addition & 2 deletions crates/bitwarden-send/src/remove_password.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ async fn remove_send_password<R: Repository<Send> + ?Sized>(
let resp = api_client
.sends_api()
.put_remove_password(&send_id.to_string())
.await
.map_err(ApiError::from)?;
.await?;

let send: Send = resp.try_into()?;

Expand Down
3 changes: 1 addition & 2 deletions crates/bitwarden-sync/src/sync_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,7 @@ impl SyncClient {
.api_client
.sync_api()
.get(input.exclude_subdomains)
.await
.map_err(|e| SyncError::Api(e.into()))?;
.await?;

Ok(sync)
}
Expand Down
Loading
Loading