mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 20:37:43 +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:
@ -868,8 +868,7 @@ pub fn print_if_stream(
|
||||
let _ = stderr.write_all(&bytes);
|
||||
}
|
||||
}
|
||||
})
|
||||
.expect("could not create thread");
|
||||
})?;
|
||||
}
|
||||
|
||||
if let Some(stream) = stream {
|
||||
|
@ -2,7 +2,9 @@ use miette::Diagnostic;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{ast::Operator, engine::StateWorkingSet, format_error, ParseError, Span, Value};
|
||||
use crate::{
|
||||
ast::Operator, engine::StateWorkingSet, format_error, ParseError, Span, Spanned, Value,
|
||||
};
|
||||
|
||||
/// The fundamental error type for the evaluation engine. These cases represent different kinds of errors
|
||||
/// the evaluator might face, along with helpful spans to label. An error renderer will take this error value
|
||||
@ -1361,6 +1363,15 @@ impl From<std::io::Error> for ShellError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Spanned<std::io::Error>> for ShellError {
|
||||
fn from(error: Spanned<std::io::Error>) -> Self {
|
||||
ShellError::IOErrorSpanned {
|
||||
msg: error.item.to_string(),
|
||||
span: error.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Box<dyn std::error::Error>> for ShellError {
|
||||
fn from(input: Box<dyn std::error::Error>) -> ShellError {
|
||||
ShellError::IOError {
|
||||
|
@ -3,14 +3,33 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A spanned area of interest, generic over what kind of thing is of interest
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Spanned<T>
|
||||
where
|
||||
T: Clone + std::fmt::Debug,
|
||||
{
|
||||
pub struct Spanned<T> {
|
||||
pub item: T,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
/// Helper trait to create [`Spanned`] more ergonomically.
|
||||
pub trait IntoSpanned: Sized {
|
||||
/// Wrap items together with a span into [`Spanned`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use nu_protocol::{Span, IntoSpanned};
|
||||
/// # let span = Span::test_data();
|
||||
/// let spanned = "Hello, world!".into_spanned(span);
|
||||
/// assert_eq!("Hello, world!", spanned.item);
|
||||
/// assert_eq!(span, spanned.span);
|
||||
/// ```
|
||||
fn into_spanned(self, span: Span) -> Spanned<Self>;
|
||||
}
|
||||
|
||||
impl<T> IntoSpanned for T {
|
||||
fn into_spanned(self, span: Span) -> Spanned<Self> {
|
||||
Spanned { item: self, span }
|
||||
}
|
||||
}
|
||||
|
||||
/// Spans are a global offset across all seen files, which are cached in the engine's state. The start and
|
||||
/// end offset together make the inclusive start/exclusive end pair for where to underline to highlight
|
||||
/// a given point of interest.
|
||||
|
Reference in New Issue
Block a user