Merge pull request #2389 from zed-industries/save-panics-as-structured-data

Save panics as structured data
This commit is contained in:
Joseph T. Lyons 2023-04-20 12:51:00 -04:00 committed by GitHub
commit 65f7228fed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -21,7 +21,7 @@ use log::LevelFilter;
use node_runtime::NodeRuntime; use node_runtime::NodeRuntime;
use parking_lot::Mutex; use parking_lot::Mutex;
use project::Fs; use project::Fs;
use serde_json::json; use serde::{Deserialize, Serialize};
use settings::{ use settings::{
self, settings_file::SettingsFile, KeymapFileContent, Settings, SettingsFileContent, self, settings_file::SettingsFile, KeymapFileContent, Settings, SettingsFileContent,
WorkingDirectory, WorkingDirectory,
@ -317,6 +317,30 @@ fn init_logger() {
} }
} }
#[derive(Serialize, Deserialize)]
struct LocationData {
file: String,
line: u32,
}
#[derive(Serialize, Deserialize)]
struct Panic {
thread: String,
payload: String,
#[serde(skip_serializing_if = "Option::is_none")]
location_data: Option<LocationData>,
backtrace: Vec<String>,
// TODO
// stripped_backtrace: String,
}
#[derive(Serialize)]
struct PanicRequest {
panic: Panic,
version: String,
token: String,
}
fn init_panic_hook(app_version: String) { fn init_panic_hook(app_version: String) {
let is_pty = stdout_is_a_pty(); let is_pty = stdout_is_a_pty();
panic::set_hook(Box::new(move |info| { panic::set_hook(Box::new(move |info| {
@ -333,25 +357,23 @@ fn init_panic_hook(app_version: String) {
}, },
}; };
let message = match info.location() { let panic_data = Panic {
Some(location) => { thread: thread.into(),
format!( payload: payload.into(),
"thread '{}' panicked at '{}'\n{}:{}\n{:?}", location_data: info.location().map(|location| LocationData {
thread, file: location.file().into(),
payload, line: location.line(),
location.file(), }),
location.line(), backtrace: format!("{:?}", backtrace)
backtrace .split("\n")
) .map(|line| line.to_string())
} .collect(),
None => format!( // modified_backtrace: None,
"thread '{}' panicked at '{}'\n{:?}",
thread, payload, backtrace
),
}; };
if let Some(panic_data_json) = serde_json::to_string_pretty(&panic_data).log_err() {
if is_pty { if is_pty {
eprintln!("{}", message); eprintln!("{}", panic_data_json);
return; return;
} }
@ -364,9 +386,10 @@ fn init_panic_hook(app_version: String) {
.open(&panic_file_path) .open(&panic_file_path)
.log_err(); .log_err();
if let Some(mut panic_file) = panic_file { if let Some(mut panic_file) = panic_file {
write!(&mut panic_file, "{}", message).log_err(); write!(&mut panic_file, "{}", panic_data_json).log_err();
panic_file.flush().log_err(); panic_file.flush().log_err();
} }
}
})); }));
} }
@ -402,15 +425,17 @@ fn upload_previous_panics(http: Arc<dyn HttpClient>, cx: &mut AppContext) {
}; };
if diagnostics_telemetry { if diagnostics_telemetry {
let text = smol::fs::read_to_string(&child_path) let panic_data_text = smol::fs::read_to_string(&child_path)
.await .await
.context("error reading panic file")?; .context("error reading panic file")?;
let body = serde_json::to_string(&json!({
"text": text, let body = serde_json::to_string(&PanicRequest {
"version": version, panic: serde_json::from_str(&panic_data_text)?,
"token": ZED_SECRET_CLIENT_TOKEN, version: version.to_string(),
})) token: ZED_SECRET_CLIENT_TOKEN.into(),
})
.unwrap(); .unwrap();
let request = Request::post(&panic_report_url) let request = Request::post(&panic_report_url)
.redirect_policy(isahc::config::RedirectPolicy::Follow) .redirect_policy(isahc::config::RedirectPolicy::Follow)
.header("Content-Type", "application/json") .header("Content-Type", "application/json")