|
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