fix(multipart): Use correct discard reasons#5950
Conversation
bab71e8 to
3ba99b0
Compare
3ba99b0 to
c055532
Compare
ae96e45 to
d4025f1
Compare
| let envelope = items.map(|items, records| { | ||
| if items.iter().any(|i| i.creates_event()) { | ||
| records.modify_by(DataCategory::Error, 1); | ||
| } | ||
| Box::new(Envelope::from_request(Some(path.event_id), meta).with_items(items)) |
There was a problem hiding this comment.
Steered away from a common envelope-creation function because of the complexity of keeping records correct in all cases. Opened #5949 to address this
…men-minidump-outcomes
…men-minidump-outcomes
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit eeb45a7. Configure here.
jjbayer
left a comment
There was a problem hiding this comment.
Please take a look at https://github.com/getsentry/relay/pull/5950/changes#r3202052807 before merging.
| impl BadStoreRequest { | ||
| pub fn to_outcome(&self) -> Option<Outcome> { | ||
| let discard_reason = match self { | ||
| Self::InvalidCompressionContainer(_) => DiscardReason::InvalidCompression, | ||
| Self::InvalidMinidump => DiscardReason::InvalidMinidump, | ||
| #[cfg(sentry)] | ||
| Self::InvalidProsperodump => DiscardReason::InvalidProsperodump, | ||
| Self::MissingMinidump => DiscardReason::MissingMinidumpUpload, | ||
| #[cfg(sentry)] | ||
| Self::MissingProsperodump => DiscardReason::MissingProsperodumpUpload, | ||
| Self::Overflow(item_type) => DiscardReason::TooLarge(*item_type), | ||
| _ => DiscardReason::Internal, | ||
| }; | ||
| Some(Outcome::Invalid(discard_reason)) | ||
| } | ||
| } |
There was a problem hiding this comment.
Not a blocker, but converting BadStoreRequest to a DiscardReason seems backward to me. It would be better to make the functions that currently return BadStoreRequest return a DiscardReason instead, and make that to a BadStoreRequest only if we reject the entire request.
There was a problem hiding this comment.
I agree, and maybe we don't need BadStoreRequest at all. But changing all the functions that return BadStoreRequest seems out of scope for this PR.
There was a problem hiding this comment.
Ideally we have proper scoped errors for these cases.
Also not really happy about:
impl From<Rejected<BadStoreRequest>> for BadStoreRequest {
fn from(rejected: Rejected<BadStoreRequest>) -> Self {
rejected.into_inner()
}
}This also seems like a workaround rather than a solution and if it was explicit Rejected::into_inner it'd be more visible where there can be improvements.
That being said, this shouldn't block an overall improvement.
| inner.set_filename(remove_container_extension(minidump_filename).to_owned()) | ||
| items.try_modify(|items, records| -> Result<(), BadStoreRequest> { | ||
| let minidump_item = &mut items[minidump_idx]; | ||
| minidump_item.set_payload(Minidump, payload); |
There was a problem hiding this comment.
Not related to this PR, but I noticed it: we always qualify enum variants:
| minidump_item.set_payload(Minidump, payload); | |
| minidump_item.set_payload(ContentType::Minidump, payload); |
There was a problem hiding this comment.
I'm confused, is qualifying something we should or shouldn't do?
There was a problem hiding this comment.
Our convention is to always use the qualified path, that is MyEnum::MyVariant.
| // Doing these operations does not make sense if we already streamed the minidump to objectstore. | ||
| if !minidump_item.is_attachment_ref() { | ||
| let payload = minidump_item.payload(); | ||
| if !items[minidump_idx].is_attachment_ref() { |
There was a problem hiding this comment.
It's a bit nitpicky, but we do have a guideline to avoid slice syntax as it introduces a place where things can panic, see: https://develop.sentry.dev/engineering-practices/rust/#use-get-instead-of-slice-syntax
This policy while at times may seem useless, it did serve us well so far.
Something like this should do:
| if !items[minidump_idx].is_attachment_ref() { | |
| if !items.get(minidump_idx).is_some_and(|item| item.is_attachment_ref()) { |
Or some variant of if let Some(x) = _.get() && x.foo()
| impl BadStoreRequest { | ||
| pub fn to_outcome(&self) -> Option<Outcome> { | ||
| let discard_reason = match self { | ||
| Self::InvalidCompressionContainer(_) => DiscardReason::InvalidCompression, | ||
| Self::InvalidMinidump => DiscardReason::InvalidMinidump, | ||
| #[cfg(sentry)] | ||
| Self::InvalidProsperodump => DiscardReason::InvalidProsperodump, | ||
| Self::MissingMinidump => DiscardReason::MissingMinidumpUpload, | ||
| #[cfg(sentry)] | ||
| Self::MissingProsperodump => DiscardReason::MissingProsperodumpUpload, | ||
| Self::Overflow(item_type) => DiscardReason::TooLarge(*item_type), | ||
| _ => DiscardReason::Internal, | ||
| }; | ||
| Some(Outcome::Invalid(discard_reason)) | ||
| } | ||
| } |
There was a problem hiding this comment.
Ideally we have proper scoped errors for these cases.
Also not really happy about:
impl From<Rejected<BadStoreRequest>> for BadStoreRequest {
fn from(rejected: Rejected<BadStoreRequest>) -> Self {
rejected.into_inner()
}
}This also seems like a workaround rather than a solution and if it was explicit Rejected::into_inner it'd be more visible where there can be improvements.
That being said, this shouldn't block an overall improvement.
c0efc1c to
ffe03f2
Compare
…men-minidump-outcomes
ffe03f2 to
0176978
Compare

Use correct discard reasons for outcomes across multipart endpoints. Also refactor from
Vec<Managed<Item>>toManaged<Items>to simplify "all-item"-operations; albeit with a tradeoff of less ergonomic operations on individual items (see the indexing used to access and modify the minidump and proserpodump).