Skip to content
Merged
Show file tree
Hide file tree
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
feat(ast_tools): better handling of formatting errors (#10025)
Improve handling of parsing/formatting errors in outputs.

Previously would panic or output an empty file, which made debugging what was causing the problem difficult. Instead output the unformatted source, so can look at it and figure out what's wrong.
  • Loading branch information
overlookmotel committed Mar 25, 2025
commit 68ee796305e8f4e5e471f987ece907111dfbc7fa
15 changes: 13 additions & 2 deletions tasks/ast_tools/src/output/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::{
process::{Command, Stdio},
};

use crate::log;

use super::add_header;

/// Format Javascript/Typescript code, and add header.
Expand All @@ -16,7 +18,8 @@ fn format(source_text: &str) -> String {
let mut dprint = Command::new("dprint")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.args(["fmt", "--stdin", "dummy.ts"])
.stderr(Stdio::piped())
.args(["fmt", "--stdin", "placeholder_filename.ts"])
.spawn()
.expect("Failed to run dprint (is it installed?)");

Expand All @@ -25,5 +28,13 @@ fn format(source_text: &str) -> String {
stdin.flush().unwrap();

let output = dprint.wait_with_output().unwrap();
String::from_utf8(output.stdout).unwrap()
if output.status.success() {
String::from_utf8(output.stdout).unwrap()
} else {
// Formatting failed. Return unformatted code, to aid debugging.
let error =
String::from_utf8(output.stderr).unwrap_or_else(|_| "Unknown error".to_string());
log!("FAILED TO FORMAT JS/TS code:\n{error}");
source_text.to_string()
}
}
2 changes: 1 addition & 1 deletion tasks/ast_tools/src/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl Output {

let (path, code) = match self {
Self::Rust { path, tokens } => {
let code = print_rust(tokens, &generator_path);
let code = print_rust(&tokens, &generator_path);
(path, code)
}
Self::RustString { path, code } => {
Expand Down
27 changes: 24 additions & 3 deletions tasks/ast_tools/src/output/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,23 @@ use lazy_regex::{Captures, Lazy, Regex, lazy_regex, regex::Replacer};
use proc_macro2::TokenStream;
use syn::parse2;

use crate::log;

use super::add_header;

/// Format Rust code, and add header.
pub fn print_rust(tokens: TokenStream, generator_path: &str) -> String {
let code = prettyplease::unparse(&parse2(tokens).unwrap());
pub fn print_rust(tokens: &TokenStream, generator_path: &str) -> String {
// Note: Cloning `TokenStream` is cheap, because internally it's an `Rc`
let file = match parse2(tokens.clone()) {
Ok(file) => file,
Err(err) => {
// Parsing failed. Return unformatted code, to aid debugging.
log!("FAILED TO PARSE Rust code:\n{err}");
return tokens.to_string();
}
};

let code = prettyplease::unparse(&file);
let code = COMMENT_REGEX.replace_all(&code, CommentReplacer).to_string();
let code = add_header(&code, generator_path, "//");
rust_fmt(&code)
Expand All @@ -24,6 +36,7 @@ pub fn rust_fmt(source_text: &str) -> String {
let mut rustfmt = Command::new("rustfmt")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("Failed to run rustfmt (is it installed?)");

Expand All @@ -32,7 +45,15 @@ pub fn rust_fmt(source_text: &str) -> String {
stdin.flush().unwrap();

let output = rustfmt.wait_with_output().unwrap();
String::from_utf8(output.stdout).unwrap()
if output.status.success() {
String::from_utf8(output.stdout).unwrap()
} else {
// Formatting failed. Return unformatted code, to aid debugging.
let error =
String::from_utf8(output.stderr).unwrap_or_else(|_| "Unknown error".to_string());
log!("FAILED TO FORMAT Rust code:\n{error}");
source_text.to_string()
}
}

/// Replace doc comments which start with `@` with plain comments or line breaks.
Expand Down