diff --git a/CHANGELOG.md b/CHANGELOG.md index 81523389df6..e84cda9e8fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ **Bug Fixes**: +- Preserve user specified event values in Unreal crash reports. ([#4882](https://github.com/getsentry/relay/pull/4882)) - OS name parsing of Unreal crash reports. ([#4854](https://github.com/getsentry/relay/pull/4854)) **Internal**: diff --git a/relay-server/src/utils/unreal.rs b/relay-server/src/utils/unreal.rs index 6a14cb0d06a..7fa4a21e3b3 100644 --- a/relay-server/src/utils/unreal.rs +++ b/relay-server/src/utils/unreal.rs @@ -206,18 +206,17 @@ fn merge_unreal_context(event: &mut Event, context: Unreal4Context) { }; if let Some(msg) = runtime_props.error_message.take() { - event - .logentry - .get_or_insert_with(LogEntry::default) - .formatted = Annotated::new(Message::from(msg)); + let logentry = event.logentry.get_or_insert_with(LogEntry::default); + if logentry.formatted.is_empty() { + logentry.formatted = Annotated::new(Message::from(msg)); + } } if let Some(username) = runtime_props.username.take() { - event - .user - .get_or_insert_with(User::default) - .username - .set_value(Some(username.into())); + let user = event.user.get_or_insert_with(User::default); + if user.username.is_empty() { + user.username.set_value(Some(username.into())); + } } if let Some(login_id) = &runtime_props.login_id { @@ -232,47 +231,65 @@ fn merge_unreal_context(event: &mut Event, context: Unreal4Context) { if let Some(memory_physical) = runtime_props.memory_stats_total_physical.take() { let device_context = contexts.get_or_default::(); - device_context.memory_size = Annotated::new(memory_physical); + if device_context.memory_size.is_empty() { + device_context.memory_size = Annotated::new(memory_physical); + } } // OS information is likely overwritten by Minidump processing later. if let Some(os_major) = runtime_props.misc_os_version_major.take() { let os_context = contexts.get_or_default::(); - os_context.raw_description = Annotated::new(os_major); + if os_context.raw_description.is_empty() { + os_context.raw_description = Annotated::new(os_major); + } } // See https://github.com/EpicGames/UnrealEngine/blob/5.3.2-release/Engine/Source/Runtime/RHI/Private/DynamicRHI.cpp#L368-L376 if let Some(adapter_name) = context.engine_data.get("RHI.AdapterName") { let gpu_context = contexts.get_or_default::(); - gpu_context.name = Annotated::new(adapter_name.into()); + if gpu_context.name.is_empty() { + gpu_context.name = Annotated::new(adapter_name.into()); + } } else if let Some(gpu_brand) = runtime_props.misc_primary_gpu_brand.take() { let gpu_context = contexts.get_or_default::(); - gpu_context.name = Annotated::new(gpu_brand); + if gpu_context.name.is_empty() { + gpu_context.name = Annotated::new(gpu_brand); + } } if let Some(device_id) = context.engine_data.get("RHI.DeviceId") { let gpu_context = contexts.get_or_default::(); - gpu_context.id = Annotated::new(Value::String(device_id.into())); + if gpu_context.id.is_empty() { + gpu_context.id = Annotated::new(Value::String(device_id.into())); + } } if let Some(feature_level) = context.engine_data.get("RHI.FeatureLevel") { let gpu_context = contexts.get_or_default::(); - gpu_context.graphics_shader_level = Annotated::new(feature_level.into()); + if gpu_context.graphics_shader_level.is_empty() { + gpu_context.graphics_shader_level = Annotated::new(feature_level.into()); + } } if let Some(vendor_name) = context.engine_data.get("RHI.GPUVendor") { let gpu_context = contexts.get_or_default::(); - gpu_context.vendor_name = Annotated::new(vendor_name.into()); + if gpu_context.vendor_name.is_empty() { + gpu_context.vendor_name = Annotated::new(vendor_name.into()); + } } if let Some(driver_version) = context.engine_data.get("RHI.UserDriverVersion") { let gpu_context = contexts.get_or_default::(); - gpu_context.version = Annotated::new(driver_version.into()); + if gpu_context.version.is_empty() { + gpu_context.version = Annotated::new(driver_version.into()); + } } if let Some(rhi_name) = context.engine_data.get("RHI.RHIName") { let gpu_context = contexts.get_or_default::(); - gpu_context.api_type = Annotated::new(rhi_name.into()); + if gpu_context.api_type.is_empty() { + gpu_context.api_type = Annotated::new(rhi_name.into()); + } } if event.level.is_empty() { @@ -377,6 +394,8 @@ pub fn process_unreal_envelope( #[cfg(test)] mod tests { + use relay_protocol::SerializableAnnotated; + use super::*; fn get_context() -> Unreal4Context { @@ -572,4 +591,82 @@ mod tests { LenientString("ebff51ef3c4878627823eebd9ff40eb4".to_owned()) ); } + + #[test] + fn test_merge_unreal_context_is_input_preserved() { + let context = get_context(); + + let mut event = Event::default(); + + let logentry = event.logentry.get_or_insert_with(LogEntry::default); + logentry.formatted = Annotated::new("error_message".to_owned().into()); + + let user = event.user.get_or_insert_with(User::default); + user.username = Annotated::new("user_name".to_owned().into()); + + let contexts = event.contexts.get_or_insert_with(Contexts::default); + + let device_context = contexts.get_or_default::(); + device_context.memory_size = Annotated::new(123456789); + + let os_context = contexts.get_or_default::(); + os_context.name = Annotated::new("os_name".to_owned()); + os_context.raw_description = Annotated::new("my own raw desc".to_owned()); + + let gpu_context = contexts.get_or_default::(); + gpu_context.name = Annotated::new("adapter_name".to_owned()); + gpu_context.id = Annotated::new(Value::String("device_id".to_owned())); + gpu_context.graphics_shader_level = Annotated::new("feature_level".to_owned()); + gpu_context.vendor_name = Annotated::new("vendor_name".to_owned()); + gpu_context.version = Annotated::new("driver_version".to_owned()); + gpu_context.api_type = Annotated::new("rhi_name".to_owned()); + + merge_unreal_context(&mut event, context); + + let event = Annotated::new(event); + insta::assert_json_snapshot!(SerializableAnnotated(&event), @r###" + { + "logentry": { + "formatted": "error_message" + }, + "user": { + "username": "user_name" + }, + "contexts": { + "device": { + "memory_size": 123456789, + "type": "device" + }, + "gpu": { + "name": "adapter_name", + "version": "driver_version", + "id": "device_id", + "vendor_name": "vendor_name", + "api_type": "rhi_name", + "graphics_shader_level": "feature_level", + "type": "gpu" + }, + "os": { + "name": "os_name", + "raw_description": "my own raw desc", + "type": "os" + }, + "unreal": { + "custom": { + "CrashVersion": "3", + "PlatformFullName": "Win64 [Windows 10 64b]" + }, + "memory_stats_total_virtual": 140737488224256, + "misc_cpu_brand": "Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz", + "misc_cpu_vendor": "GenuineIntel", + "misc_primary_gpu_brand": "Parallels Display Adapter (WDDM)" + } + }, + "sdk": { + "name": "unreal.crashreporter", + "version": "1.0" + } + } + "###); + } }