mirror of
https://github.com/nushell/nushell.git
synced 2025-08-10 03:38:07 +02:00
Replace panics with errors in thread spawning (#12040)
# Description Replace panics with errors in thread spawning. Also adds `IntoSpanned` trait for easily constructing `Spanned`, and an implementation of `From<Spanned<std::io::Error>>` for `ShellError`, which is used to provide context for the error wherever there was a span conveniently available. In general this should make it more convenient to do the right thing with `std::io::Error` and always add a span to it when it's possible to do so. # User-Facing Changes Fewer panics! # Tests + Formatting - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib`
This commit is contained in:
@ -1,7 +1,8 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, IntoPipelineData, PipelineData, Record, ShellError, Signature, Type, Value,
|
||||
Category, Example, IntoPipelineData, IntoSpanned, PipelineData, Record, ShellError, Signature,
|
||||
Type, Value,
|
||||
};
|
||||
|
||||
use std::thread;
|
||||
@ -52,9 +53,9 @@ impl Command for Complete {
|
||||
// consumes the first 65535 bytes
|
||||
// So we need a thread to receive stderr message, then the current thread can continue to consume
|
||||
// stdout messages.
|
||||
let stderr_handler = stderr.map(|stderr| {
|
||||
let stderr_span = stderr.span;
|
||||
(
|
||||
let stderr_handler = stderr
|
||||
.map(|stderr| {
|
||||
let stderr_span = stderr.span;
|
||||
thread::Builder::new()
|
||||
.name("stderr consumer".to_string())
|
||||
.spawn(move || {
|
||||
@ -65,10 +66,10 @@ impl Command for Complete {
|
||||
Ok::<_, ShellError>(Value::binary(stderr.item, stderr.span))
|
||||
}
|
||||
})
|
||||
.expect("failed to create thread"),
|
||||
stderr_span,
|
||||
)
|
||||
});
|
||||
.map(|handle| (handle, stderr_span))
|
||||
.map_err(|err| err.into_spanned(call.head))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
if let Some(stdout) = stdout {
|
||||
let stdout = stdout.into_bytes()?;
|
||||
|
@ -2,6 +2,7 @@ use nu_cmd_base::hook::eval_hook;
|
||||
use nu_engine::env_to_strings;
|
||||
use nu_engine::eval_expression;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::IntoSpanned;
|
||||
use nu_protocol::NuGlob;
|
||||
use nu_protocol::{
|
||||
ast::{Call, Expr},
|
||||
@ -438,7 +439,7 @@ impl ExternalCommand {
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.expect("Failed to create thread");
|
||||
.map_err(|e| e.into_spanned(head))?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -526,7 +527,7 @@ impl ExternalCommand {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}).expect("Failed to create thread");
|
||||
}).map_err(|e| e.into_spanned(head))?;
|
||||
|
||||
let (stderr_tx, stderr_rx) = mpsc::sync_channel(OUTPUT_BUFFERS_IN_FLIGHT);
|
||||
if redirect_stderr {
|
||||
@ -543,7 +544,7 @@ impl ExternalCommand {
|
||||
read_and_redirect_message(stderr, stderr_tx, stderr_ctrlc);
|
||||
Ok::<(), ShellError>(())
|
||||
})
|
||||
.expect("Failed to create thread");
|
||||
.map_err(|e| e.into_spanned(head))?;
|
||||
}
|
||||
|
||||
let stdout_receiver = ChannelReceiver::new(stdout_rx);
|
||||
|
Reference in New Issue
Block a user