diff --git a/services/blob/src/database/client.rs b/services/blob/src/database/client.rs --- a/services/blob/src/database/client.rs +++ b/services/blob/src/database/client.rs @@ -83,7 +83,7 @@ .await .map_err(|err| { debug!("DynamoDB client failed to delete blob item: {:?}", err); - DBError::AwsSdk(err.into()) + DBError::AwsSdk(Box::new(err.into())) })?; Ok(()) } @@ -170,7 +170,7 @@ .await .map_err(|err| { debug!("DynamoDB client failed to run transaction: {:?}", err); - DBError::AwsSdk(err.into()) + DBError::AwsSdk(Box::new(err.into())) })?; Ok(()) } @@ -202,7 +202,7 @@ .await .map_err(|err| { error!("DynamoDB client failed to query holders: {:?}", err); - DBError::AwsSdk(err.into()) + DBError::AwsSdk(Box::new(err.into())) })?; let Some(items) = response.items else { @@ -271,7 +271,7 @@ .await .map_err(|err| { error!("DynamoDB client failed to query unchecked items: {:?}", err); - DBError::AwsSdk(err.into()) + DBError::AwsSdk(Box::new(err.into())) })?; let Some(items) = response.items else { @@ -383,7 +383,7 @@ } err => { debug!("DynamoDB client failed to insert: {:?}", err); - DBError::AwsSdk(err) + DBError::AwsSdk(Box::new(err)) } }) } @@ -402,7 +402,7 @@ .await .map_err(|err| { debug!("DynamoDB client failed to get item: {:?}", err); - DBError::AwsSdk(err.into()) + DBError::AwsSdk(Box::new(err.into())) }) .map(|response| response.item) } diff --git a/services/blob/src/database/errors.rs b/services/blob/src/database/errors.rs --- a/services/blob/src/database/errors.rs +++ b/services/blob/src/database/errors.rs @@ -10,7 +10,7 @@ )] pub enum Error { #[display(...)] - AwsSdk(DynamoDBError), + AwsSdk(Box), #[display(...)] Attribute(DBItemError), #[display(...)] @@ -25,7 +25,7 @@ fn from(value: comm_lib::database::Error) -> Self { use comm_lib::database::Error as E; match value { - E::AwsSdk(err) => Self::AwsSdk(err), + E::AwsSdk(err) => Self::AwsSdk(Box::new(err)), E::Attribute(err) => Self::Attribute(err), E::MaxRetriesExceeded => Self::MaxRetriesExceeded, } diff --git a/services/blob/src/http/errors.rs b/services/blob/src/http/errors.rs --- a/services/blob/src/http/errors.rs +++ b/services/blob/src/http/errors.rs @@ -20,14 +20,18 @@ ErrorConflict("blob already exists") } BlobServiceError::DB(db_err) => match db_err { - DBError::AwsSdk(DynamoDBError::InternalServerError(_)) - | DBError::AwsSdk( - DynamoDBError::ProvisionedThroughputExceededException(_), - ) - | DBError::AwsSdk(DynamoDBError::RequestLimitExceeded(_)) => { - warn!("AWS transient error occurred"); - ErrorServiceUnavailable("please retry") - } + DBError::AwsSdk(aws_err) => match aws_err.as_ref() { + DynamoDBError::InternalServerError(_) + | DynamoDBError::ProvisionedThroughputExceededException(_) + | DynamoDBError::RequestLimitExceeded(_) => { + warn!("AWS transient error occurred"); + ErrorServiceUnavailable("please retry") + } + unexpected => { + error!("Received an unexpected AWS error: {0:?} - {0}", unexpected); + ErrorInternalServerError("server error") + } + }, DBError::Blob(BlobDBError::InvalidInput(_)) => { ErrorBadRequest("bad request") } @@ -37,11 +41,16 @@ } }, BlobServiceError::S3(s3_err) => match s3_err { - S3Error::AwsSdk(aws_sdk_s3::Error::NotFound(_)) - | S3Error::AwsSdk(aws_sdk_s3::Error::NoSuchKey(_)) => { - error!("Data inconsistency! Blob is present in database but not present in S3!"); - ErrorInternalServerError("server error") - } + S3Error::AwsSdk(aws_err) => match aws_err.as_ref() { + aws_sdk_s3::Error::NotFound(_) | aws_sdk_s3::Error::NoSuchKey(_) => { + error!("Data inconsistency! Blob is present in database but not present in S3!"); + ErrorInternalServerError("server error") + } + err => { + error!("Received an unexpected AWS S3 error: {0:?} - {0}", err); + ErrorInternalServerError("server error") + } + }, S3Error::EmptyUpload => ErrorBadRequest("empty upload"), unexpected => { error!("Received an unexpected S3 error: {0:?} - {0}", unexpected); diff --git a/services/blob/src/s3.rs b/services/blob/src/s3.rs --- a/services/blob/src/s3.rs +++ b/services/blob/src/s3.rs @@ -12,7 +12,7 @@ )] pub enum Error { #[display(...)] - AwsSdk(S3Error), + AwsSdk(Box), #[display(...)] ByteStream(std::io::Error), #[display(...)] @@ -133,7 +133,7 @@ .await .map_err(|e| { error!("S3 failed to get object metadata"); - Error::AwsSdk(e.into()) + Error::AwsSdk(Box::new(e.into())) })?; Ok(response) @@ -172,7 +172,7 @@ let response = request.send().await.map_err(|e| { error!("S3 failed to get object"); - Error::AwsSdk(e.into()) + Error::AwsSdk(Box::new(e.into())) })?; let data = response.body.collect().await.map_err(|e| { error!("S3 failed to stream object bytes"); @@ -192,7 +192,7 @@ .await .map_err(|e| { error!("S3 failed to delete object"); - Error::AwsSdk(e.into()) + Error::AwsSdk(Box::new(e.into())) })?; Ok(()) @@ -219,7 +219,7 @@ .await .map_err(|e| { error!("S3 failed to batch delete objects"); - Error::AwsSdk(e.into()) + Error::AwsSdk(Box::new(e.into())) })?; Ok(()) @@ -250,7 +250,7 @@ .await .map_err(|e| { error!("S3 failed to start upload session"); - Error::AwsSdk(e.into()) + Error::AwsSdk(Box::new(e.into())) })?; let upload_id = multipart_upload_res.upload_id().ok_or_else(|| { @@ -284,7 +284,7 @@ .await .map_err(|e| { error!("Failed to add upload part"); - Error::AwsSdk(e.into()) + Error::AwsSdk(Box::new(e.into())) })?; let completed_part = CompletedPart::builder() @@ -322,7 +322,7 @@ .await .map_err(|e| { error!("Failed to finish upload session"); - Error::AwsSdk(e.into()) + Error::AwsSdk(Box::new(e.into())) })?; debug!(upload_id = self.upload_id, "Multipart upload complete");