Skip to content

Commit 7fe033d

Browse files
committed
handle S3 "KeyTooLongError" as PathNotFoundError in storage
1 parent 8fff5f5 commit 7fe033d

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

src/storage/s3.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::{Context as _, Error};
44
use aws_config::BehaviorVersion;
55
use aws_sdk_s3::{
66
config::{retry::RetryConfig, Region},
7-
error::SdkError,
7+
error::{ProvideErrorMetadata, SdkError},
88
operation::{get_object::GetObjectError, head_object::HeadObjectError},
99
types::{Delete, ObjectIdentifier, Tag, Tagging},
1010
Client,
@@ -21,6 +21,19 @@ use tracing::{error, warn};
2121
const PUBLIC_ACCESS_TAG: &str = "static-cloudfront-access";
2222
const PUBLIC_ACCESS_VALUE: &str = "allow";
2323

24+
fn err_is_not_found<E>(err: &SdkError<E>) -> bool
25+
where
26+
E: ProvideErrorMetadata,
27+
{
28+
match err {
29+
SdkError::ServiceError(err) => {
30+
err.raw().status().as_u16() == http::StatusCode::NOT_FOUND.as_u16()
31+
}
32+
e if e.code() == Some("KeyTooLongError") => true,
33+
_ => false,
34+
}
35+
}
36+
2437
pub(super) struct S3Backend {
2538
client: Client,
2639
bucket: String,
@@ -78,11 +91,11 @@ impl S3Backend {
7891
{
7992
Ok(_) => Ok(true),
8093
Err(SdkError::ServiceError(err))
81-
if (matches!(err.err(), HeadObjectError::NotFound(_))
82-
|| err.raw().status().as_u16() == http::StatusCode::NOT_FOUND.as_u16()) =>
94+
if matches!(err.err(), HeadObjectError::NotFound(_)) =>
8395
{
8496
Ok(false)
8597
}
98+
Err(err) if err_is_not_found(&err) => Ok(false),
8699
Err(other) => Err(other.into()),
87100
}
88101
}
@@ -101,13 +114,7 @@ impl S3Backend {
101114
.iter()
102115
.filter(|tag| tag.key() == PUBLIC_ACCESS_TAG)
103116
.any(|tag| tag.value() == PUBLIC_ACCESS_VALUE)),
104-
Err(SdkError::ServiceError(err)) => {
105-
if err.raw().status().as_u16() == http::StatusCode::NOT_FOUND.as_u16() {
106-
Err(super::PathNotFoundError.into())
107-
} else {
108-
Err(err.into_err().into())
109-
}
110-
}
117+
Err(err) if err_is_not_found(&err) => Err(super::PathNotFoundError.into()),
111118
Err(other) => Err(other.into()),
112119
}
113120
}
@@ -139,13 +146,7 @@ impl S3Backend {
139146
.await
140147
{
141148
Ok(_) => Ok(()),
142-
Err(SdkError::ServiceError(err)) => {
143-
if err.raw().status().as_u16() == http::StatusCode::NOT_FOUND.as_u16() {
144-
Err(super::PathNotFoundError.into())
145-
} else {
146-
Err(err.into_err().into())
147-
}
148-
}
149+
Err(err) if err_is_not_found(&err) => Err(super::PathNotFoundError.into()),
149150
Err(other) => Err(other.into()),
150151
}
151152
}
@@ -163,16 +164,16 @@ impl S3Backend {
163164
.key(path)
164165
.set_range(range.map(|r| format!("bytes={}-{}", r.start(), r.end())))
165166
.send()
167+
.await
166168
.map_err(|err| match err {
167169
SdkError::ServiceError(err)
168-
if (matches!(err.err(), GetObjectError::NoSuchKey(_))
169-
|| err.raw().status().as_u16() == http::StatusCode::NOT_FOUND.as_u16()) =>
170+
if matches!(err.err(), GetObjectError::NoSuchKey(_)) =>
170171
{
171172
super::PathNotFoundError.into()
172173
}
174+
err if err_is_not_found(&err) => super::PathNotFoundError.into(),
173175
err => Error::from(err),
174-
})
175-
.await?;
176+
})?;
176177

177178
let mut content = crate::utils::sized_buffer::SizedBuffer::new(max_size);
178179
content.reserve(

0 commit comments

Comments
 (0)