Attach minidump errors to uploaded crash events (#36527)

Julia Ryan and Max Brunsfeld created

We see a bunch of crash events with truncated minidumps where they have
a valid header but no events. We think this is due to an issue
generating them, so we're attaching the relevant result to the uploaded
tags.

Release Notes:

- N/A

Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>

Change summary

crates/crashes/src/crashes.rs | 12 ++++++------
crates/zed/src/reliability.rs |  3 +++
2 files changed, 9 insertions(+), 6 deletions(-)

Detailed changes

crates/crashes/src/crashes.rs 🔗

@@ -128,6 +128,7 @@ pub struct CrashServer {
 pub struct CrashInfo {
     pub init: InitCrashHandler,
     pub panic: Option<CrashPanic>,
+    pub minidump_error: Option<String>,
 }
 
 #[derive(Debug, Deserialize, Serialize, Clone)]
@@ -162,16 +163,14 @@ impl minidumper::ServerHandler for CrashServer {
     }
 
     fn on_minidump_created(&self, result: Result<MinidumpBinary, minidumper::Error>) -> LoopAction {
-        match result {
+        let minidump_error = match result {
             Ok(mut md_bin) => {
                 use io::Write;
                 let _ = md_bin.file.flush();
-                info!("wrote minidump to disk {:?}", md_bin.path);
+                None
             }
-            Err(e) => {
-                info!("failed to write minidump: {:#}", e);
-            }
-        }
+            Err(e) => Some(format!("{e:?}")),
+        };
 
         let crash_info = CrashInfo {
             init: self
@@ -180,6 +179,7 @@ impl minidumper::ServerHandler for CrashServer {
                 .expect("not initialized")
                 .clone(),
             panic: self.panic_info.get().cloned(),
+            minidump_error,
         };
 
         let crash_data_path = paths::logs_dir()

crates/zed/src/reliability.rs 🔗

@@ -607,6 +607,9 @@ async fn upload_minidump(
         // TODO: add gpu-context, feature-flag-context, and more of device-context like gpu
         // name, screen resolution, available ram, device model, etc
     }
+    if let Some(minidump_error) = metadata.minidump_error.clone() {
+        form = form.text("minidump_error", minidump_error);
+    }
 
     let mut response_text = String::new();
     let mut response = http.send_multipart_form(endpoint, form).await?;