|
1 | 1 | use aws_credential_types::Credentials; |
2 | 2 | use aws_sdk_cloudfront::config::retry::RetryConfig; |
3 | 3 | use aws_sdk_cloudfront::config::{BehaviorVersion, Region}; |
| 4 | +use aws_sdk_cloudfront::error::{BuildError, SdkError}; |
| 5 | +use aws_sdk_cloudfront::operation::create_invalidation::CreateInvalidationError; |
4 | 6 | use aws_sdk_cloudfront::types::{InvalidationBatch, Paths}; |
5 | 7 | use aws_sdk_cloudfront::{Client, Config}; |
6 | 8 | use tracing::{debug, instrument, warn}; |
7 | 9 |
|
| 10 | +#[derive(Debug, thiserror::Error)] |
| 11 | +pub enum CloudFrontError { |
| 12 | + #[error(transparent)] |
| 13 | + BuildError(#[from] BuildError), |
| 14 | + #[error(transparent)] |
| 15 | + SdkError(Box<SdkError<CreateInvalidationError>>), |
| 16 | +} |
| 17 | + |
| 18 | +impl From<SdkError<CreateInvalidationError>> for CloudFrontError { |
| 19 | + fn from(err: SdkError<CreateInvalidationError>) -> Self { |
| 20 | + CloudFrontError::SdkError(Box::new(err)) |
| 21 | + } |
| 22 | +} |
| 23 | + |
| 24 | +impl CloudFrontError { |
| 25 | + pub fn is_too_many_invalidations_error(&self) -> bool { |
| 26 | + let CloudFrontError::SdkError(sdk_error) = self else { |
| 27 | + return false; |
| 28 | + }; |
| 29 | + |
| 30 | + let Some(service_error) = sdk_error.as_service_error() else { |
| 31 | + return false; |
| 32 | + }; |
| 33 | + |
| 34 | + service_error.is_too_many_invalidations_in_progress() |
| 35 | + } |
| 36 | +} |
| 37 | + |
8 | 38 | pub struct CloudFront { |
9 | 39 | client: Client, |
10 | 40 | distribution_id: String, |
@@ -36,13 +66,13 @@ impl CloudFront { |
36 | 66 | /// Invalidate a file on CloudFront |
37 | 67 | /// |
38 | 68 | /// `path` is the path to the file to invalidate, such as `config.json`, or `re/ge/regex` |
39 | | - pub async fn invalidate(&self, path: &str) -> anyhow::Result<()> { |
| 69 | + pub async fn invalidate(&self, path: &str) -> Result<(), CloudFrontError> { |
40 | 70 | self.invalidate_many(vec![path.to_string()]).await |
41 | 71 | } |
42 | 72 |
|
43 | 73 | /// Invalidate multiple paths on Cloudfront. |
44 | 74 | #[instrument(skip(self))] |
45 | | - pub async fn invalidate_many(&self, mut paths: Vec<String>) -> anyhow::Result<()> { |
| 75 | + pub async fn invalidate_many(&self, mut paths: Vec<String>) -> Result<(), CloudFrontError> { |
46 | 76 | let now = chrono::offset::Utc::now().timestamp_micros(); |
47 | 77 |
|
48 | 78 | // We need to ensure that paths have a starting slash. |
@@ -72,15 +102,11 @@ impl CloudFront { |
72 | 102 |
|
73 | 103 | debug!("Sending invalidation request"); |
74 | 104 |
|
75 | | - match invalidation_request.send().await { |
76 | | - Ok(_) => { |
77 | | - debug!("Invalidation request successful"); |
78 | | - Ok(()) |
79 | | - } |
80 | | - Err(error) => { |
81 | | - warn!(?error, "Invalidation request failed"); |
82 | | - Err(error.into()) |
83 | | - } |
84 | | - } |
| 105 | + Ok(invalidation_request |
| 106 | + .send() |
| 107 | + .await |
| 108 | + .map(|_| ()) // We don't care about the result, just that it worked |
| 109 | + .inspect(|_| debug!("Invalidation request successful")) |
| 110 | + .inspect_err(|error| warn!(?error, "Invalidation request failed"))?) |
85 | 111 | } |
86 | 112 | } |
0 commit comments