Skip to content
Merged
Changes from all 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
23 changes: 22 additions & 1 deletion relay-server/src/services/objectstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::services::outcome::DiscardReason;
use crate::services::store::{Store, StoreAttachment, StoreEnvelope, StoreTraceItem};
use crate::services::upload::ByteStream;
use crate::statsd::{RelayCounters, RelayTimers};
use crate::utils::{BoundedStream, MeteredStream, RetryableStream, TakeOnce};
use crate::utils::{BoundedStream, MeteredStream, RetryableStream, TakeOnce, find_error_source};

use super::outcome::Outcome;

Expand Down Expand Up @@ -175,6 +175,9 @@ impl Error {
type = kind.as_str(),
attempts = self.attempts.to_string(),
);
if self.kind.is_client_error() {
return;
}
Comment on lines +178 to +180

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the code change that suppresses error logs for client errors.

relay_log::error!(
error = &self.kind as &dyn std::error::Error,
amount = self.amount,
Expand Down Expand Up @@ -222,6 +225,15 @@ impl ErrorKind {
Self::Uuid(_) => "uuid",
}
}

fn is_client_error(&self) -> bool {
match self {
ErrorKind::UploadFailed(objectstore_client::Error::Reqwest(error)) => {
find_error_source(error, is_user_error).is_some()
}
_ => false,
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client abort detection too narrow

Medium Severity

is_client_error only treats UploadFailed reqwest errors as client faults when the source chain contains an io::Error with kind UnexpectedEof or FileTooLarge. The upload endpoint already classifies the same objectstore UploadFailed reqwest failures using is_hyper_user_error, and PATCH bodies map inbound failures to io::Error::other, so many disconnects never match and still emit relay_log::error!.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6324cba. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's OK, I want to start conservatively and relax the condition if necessary.

}
}

impl OutcomeError for Error {
Expand Down Expand Up @@ -742,6 +754,15 @@ fn is_retryable(error: &objectstore_client::Error) -> bool {
}
}

fn is_user_error(error: &(dyn std::error::Error + 'static)) -> bool {
error.downcast_ref::<std::io::Error>().is_some_and(|error| {
matches!(
error.kind(),
std::io::ErrorKind::FileTooLarge | std::io::ErrorKind::UnexpectedEof
)
})
}

#[cfg(test)]
mod tests {
use relay_system::Service;
Expand Down
Loading