mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
Catch panics that happen within repl step executions
Example session: ``` » 1 + 1 The Roc compiler had an internal error. Please file a bug report at https://github.com/roc-lang/roc/issues/new Please include the following data: Error message: intentional panic Stack backtrace: 0: std::backtrace_rs::backtrace::libunwind::trace at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/../../backtrace/src/backtrace/libunwind.rs:104:5 1: std::backtrace_rs::backtrace::trace_unsynchronized at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5 2: std::backtrace::Backtrace::create at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/backtrace.rs:331:13 3: panic_hook at ./crates/repl_cli/src/lib.rs:52:41 4: call<fn(&core::panic::panic_info::PanicInfo), (&core::panic::panic_info::PanicInfo)> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:79:5 5: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/alloc/src/boxed.rs:2029:9 6: std::panicking::rust_panic_with_hook at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:785:13 7: std::panicking::begin_panic_handler::{{closure}} at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:651:13 8: std::sys_common::backtrace::__rust_end_short_backtrace at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/sys_common/backtrace.rs:171:18 9: rust_begin_unwind at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:647:5 10: core::panicking::panic_fmt at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/panicking.rs:72:14 11: step at ./crates/repl_ui/src/repl_state.rs:66:9 12: {closure#1} at ./crates/repl_cli/src/lib.rs:109:21 13: call_once<roc_repl_cli::main::{closure_env#1}, ()> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:250:5 14: call_once<roc_repl_ui::repl_state::ReplAction, roc_repl_cli::main::{closure_env#1}> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/panic/unwind_safe.rs:272:9 15: do_call<core::panic::unwind_safe::AssertUnwindSafe<roc_repl_cli::main::{closure_env#1}>, roc_repl_ui::repl_state::ReplAction> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:554:40 16: ___rust_try 17: try<roc_repl_ui::repl_state::ReplAction, core::panic::unwind_safe::AssertUnwindSafe<roc_repl_cli::main::{closure_env#1}>> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:518:19 18: catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<roc_repl_cli::main::{closure_env#1}>, roc_repl_ui::repl_state::ReplAction> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panic.rs:142:14 19: main at ./crates/repl_cli/src/lib.rs:108:30 20: main at ./crates/cli/src/main.rs:321:16 21: call_once<fn() -> core::result::Result<(), std::io::error::Error>, ()> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:250:5 22: __rust_begin_short_backtrace<fn() -> core::result::Result<(), std::io::error::Error>, core::result::Result<(), std::io::error::Error>> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/sys_common/backtrace.rs:155:18 23: {closure#0}<core::result::Result<(), std::io::error::Error>> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/rt.rs:166:18 24: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:284:13 25: std::panicking::try::do_call at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:554:40 26: std::panicking::try at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:518:19 27: std::panic::catch_unwind at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panic.rs:142:14 28: std::rt::lang_start_internal::{{closure}} at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/rt.rs:148:48 29: std::panicking::try::do_call at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:554:40 30: std::panicking::try at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:518:19 31: std::panic::catch_unwind at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panic.rs:142:14 32: std::rt::lang_start_internal at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/rt.rs:148:20 33: lang_start<core::result::Result<(), std::io::error::Error>> at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/rt.rs:165:17 34: _main Machine Target: MacArm64 ```
This commit is contained in:
parent
2263d8821a
commit
a003a16979
1 changed files with 57 additions and 1 deletions
|
@ -17,7 +17,11 @@ use rustyline::highlight::{Highlighter, PromptInfo};
|
|||
use rustyline::validate::{self, ValidationContext, ValidationResult, Validator};
|
||||
use rustyline::Config;
|
||||
use rustyline_derive::{Completer, Helper, Hinter};
|
||||
use std::any::Any;
|
||||
use std::backtrace::Backtrace;
|
||||
use std::borrow::Cow;
|
||||
use std::panic::{AssertUnwindSafe, PanicInfo};
|
||||
use std::sync::{Arc, Mutex, OnceLock};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
use crate::cli_gen::eval_llvm;
|
||||
|
@ -37,10 +41,25 @@ pub struct ReplHelper {
|
|||
state: ReplState,
|
||||
}
|
||||
|
||||
static BACKTRACE: OnceLock<Arc<Mutex<Option<String>>>> = OnceLock::new();
|
||||
|
||||
fn init_backtrace_storage() {
|
||||
BACKTRACE.get_or_init(|| Arc::new(Mutex::new(None)));
|
||||
}
|
||||
|
||||
fn panic_hook(_: &PanicInfo) {
|
||||
if let Some(storage) = BACKTRACE.get() {
|
||||
*storage.lock().unwrap() = Some(Backtrace::force_capture().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main(has_color: bool, has_header: bool) -> i32 {
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::Editor;
|
||||
|
||||
init_backtrace_storage();
|
||||
std::panic::set_hook(Box::new(panic_hook));
|
||||
|
||||
let strip_colors_if_necessary = |s: &str| {
|
||||
if has_color {
|
||||
s.to_string()
|
||||
|
@ -85,7 +104,13 @@ pub fn main(has_color: bool, has_header: bool) -> i32 {
|
|||
.state;
|
||||
|
||||
arena.reset();
|
||||
match repl_state.step(&arena, line, target, DEFAULT_PALETTE) {
|
||||
|
||||
let action = std::panic::catch_unwind(AssertUnwindSafe(|| {
|
||||
repl_state.step(&arena, line, target, DEFAULT_PALETTE)
|
||||
}))
|
||||
.unwrap_or_else(|e| notify_repl_panic(target, e));
|
||||
|
||||
match action {
|
||||
ReplAction::Eval { opt_mono, problems } => {
|
||||
let output = evaluate(opt_mono, problems, target);
|
||||
// If there was no output, don't print a blank line!
|
||||
|
@ -129,6 +154,37 @@ pub fn main(has_color: bool, has_header: bool) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
fn notify_repl_panic(target: Target, e: Box<dyn Any + Send>) -> ReplAction<'static> {
|
||||
let message = if let Some(s) = e.downcast_ref::<&str>() {
|
||||
s.to_string()
|
||||
} else if let Some(s) = e.downcast_ref::<String>() {
|
||||
s.clone()
|
||||
} else {
|
||||
"Unknown error".to_string()
|
||||
};
|
||||
|
||||
let backtrace = BACKTRACE
|
||||
.get()
|
||||
.and_then(|storage| storage.lock().unwrap().take())
|
||||
.unwrap_or_else(|| "<Backtrace not found>".to_string());
|
||||
|
||||
println!(
|
||||
"\
|
||||
The Roc compiler had an internal error.
|
||||
Please file a bug report at
|
||||
https://github.com/roc-lang/roc/issues/new
|
||||
Please include the following data:
|
||||
|
||||
Error message: {}
|
||||
Stack backtrace:
|
||||
{}
|
||||
Machine Target: {:#?}
|
||||
",
|
||||
message, backtrace, target
|
||||
);
|
||||
ReplAction::Nothing
|
||||
}
|
||||
|
||||
pub fn evaluate(
|
||||
opt_mono: Option<MonomorphizedModule<'_>>,
|
||||
problems: Problems,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue