mirror of
https://github.com/nushell/nushell.git
synced 2025-05-18 17:00:46 +02:00
Refactor: Construct IoError
from std::io::Error
instead of std::io::ErrorKind
(#15777)
This commit is contained in:
parent
c4dcfdb77b
commit
833471241a
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3996,6 +3996,7 @@ dependencies = [
|
||||
"thiserror 2.0.12",
|
||||
"typetag",
|
||||
"web-time",
|
||||
"windows 0.56.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
use nu_engine::command_prelude::*;
|
||||
use nu_protocol::{HistoryFileFormat, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
HistoryFileFormat,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use reedline::{
|
||||
FileBackedHistory, History as ReedlineHistory, HistoryItem, SearchDirection, SearchQuery,
|
||||
SqliteBackedHistory,
|
||||
@ -94,7 +97,7 @@ impl Command for History {
|
||||
})
|
||||
})
|
||||
.ok_or(IoError::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
head,
|
||||
history_path,
|
||||
))?
|
||||
@ -110,7 +113,7 @@ impl Command for History {
|
||||
})
|
||||
})
|
||||
.ok_or(IoError::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
head,
|
||||
history_path,
|
||||
))?
|
||||
|
@ -287,7 +287,7 @@ fn backup(path: &Path, span: Span) -> Result<Option<PathBuf>, ShellError> {
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(None),
|
||||
Err(e) => {
|
||||
return Err(IoError::new_internal(
|
||||
e.kind(),
|
||||
e,
|
||||
"Could not get metadata",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
@ -297,7 +297,7 @@ fn backup(path: &Path, span: Span) -> Result<Option<PathBuf>, ShellError> {
|
||||
let bak_path = find_backup_path(path, span)?;
|
||||
std::fs::copy(path, &bak_path).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err.not_found_as(NotFound::File),
|
||||
"Could not copy backup",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
|
@ -42,7 +42,7 @@ impl Command for KeybindingsListen {
|
||||
Err(e) => {
|
||||
terminal::disable_raw_mode().map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not disable raw mode",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
@ -71,18 +71,10 @@ pub fn print_events(engine_state: &EngineState) -> Result<Value, ShellError> {
|
||||
let config = engine_state.get_config();
|
||||
|
||||
stdout().flush().map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
"Could not flush stdout",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
IoError::new_internal(err, "Could not flush stdout", nu_protocol::location!())
|
||||
})?;
|
||||
terminal::enable_raw_mode().map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
"Could not enable raw mode",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
IoError::new_internal(err, "Could not enable raw mode", nu_protocol::location!())
|
||||
})?;
|
||||
|
||||
if config.use_kitty_protocol {
|
||||
@ -114,7 +106,7 @@ pub fn print_events(engine_state: &EngineState) -> Result<Value, ShellError> {
|
||||
|
||||
loop {
|
||||
let event = crossterm::event::read().map_err(|err| {
|
||||
IoError::new_internal(err.kind(), "Could not read event", nu_protocol::location!())
|
||||
IoError::new_internal(err, "Could not read event", nu_protocol::location!())
|
||||
})?;
|
||||
if event == Event::Key(KeyCode::Esc.into()) {
|
||||
break;
|
||||
@ -136,7 +128,7 @@ pub fn print_events(engine_state: &EngineState) -> Result<Value, ShellError> {
|
||||
};
|
||||
stdout.queue(crossterm::style::Print(o)).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not print output record",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
@ -144,14 +136,10 @@ pub fn print_events(engine_state: &EngineState) -> Result<Value, ShellError> {
|
||||
stdout
|
||||
.queue(crossterm::style::Print("\r\n"))
|
||||
.map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
"Could not print linebreak",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
IoError::new_internal(err, "Could not print linebreak", nu_protocol::location!())
|
||||
})?;
|
||||
stdout.flush().map_err(|err| {
|
||||
IoError::new_internal(err.kind(), "Could not flush", nu_protocol::location!())
|
||||
IoError::new_internal(err, "Could not flush", nu_protocol::location!())
|
||||
})?;
|
||||
}
|
||||
|
||||
@ -163,11 +151,7 @@ pub fn print_events(engine_state: &EngineState) -> Result<Value, ShellError> {
|
||||
}
|
||||
|
||||
terminal::disable_raw_mode().map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
"Could not disable raw mode",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
IoError::new_internal(err, "Could not disable raw mode", nu_protocol::location!())
|
||||
})?;
|
||||
|
||||
Ok(Value::nothing(Span::unknown()))
|
||||
|
@ -80,7 +80,7 @@ pub fn read_plugin_file(engine_state: &mut EngineState, plugin_file: Option<Span
|
||||
report_shell_error(
|
||||
engine_state,
|
||||
&ShellError::Io(IoError::new_internal_with_path(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not open plugin registry file",
|
||||
nu_protocol::location!(),
|
||||
plugin_path,
|
||||
@ -323,7 +323,7 @@ pub fn migrate_old_plugin_file(engine_state: &EngineState) -> bool {
|
||||
if let Err(err) = std::fs::File::create(&new_plugin_file_path)
|
||||
.map_err(|err| {
|
||||
IoError::new_internal_with_path(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not create new plugin file",
|
||||
nu_protocol::location!(),
|
||||
new_plugin_file_path.clone(),
|
||||
|
@ -28,7 +28,7 @@ pub fn evaluate_file(
|
||||
|
||||
let file_path = canonicalize_with(&path, cwd).map_err(|err| {
|
||||
IoError::new_internal_with_path(
|
||||
err.kind().not_found_as(NotFound::File),
|
||||
err.not_found_as(NotFound::File),
|
||||
"Could not access file",
|
||||
nu_protocol::location!(),
|
||||
PathBuf::from(&path),
|
||||
@ -47,7 +47,7 @@ pub fn evaluate_file(
|
||||
|
||||
let file = std::fs::read(&file_path).map_err(|err| {
|
||||
IoError::new_internal_with_path(
|
||||
err.kind().not_found_as(NotFound::File),
|
||||
err.not_found_as(NotFound::File),
|
||||
"Could not read file",
|
||||
nu_protocol::location!(),
|
||||
file_path.clone(),
|
||||
|
@ -22,6 +22,7 @@ use nu_color_config::StyleComputer;
|
||||
use nu_engine::env_to_strings;
|
||||
use nu_engine::exit::cleanup_exit;
|
||||
use nu_parser::{lex, parse, trim_quotes_str};
|
||||
use nu_protocol::shell_error;
|
||||
use nu_protocol::shell_error::io::IoError;
|
||||
use nu_protocol::{
|
||||
HistoryConfig, HistoryFileFormat, PipelineData, ShellError, Span, Spanned, Value,
|
||||
@ -854,7 +855,7 @@ fn do_auto_cd(
|
||||
report_shell_error(
|
||||
engine_state,
|
||||
&ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::DirectoryNotFound,
|
||||
span,
|
||||
PathBuf::from(&path),
|
||||
"Cannot change directory",
|
||||
@ -868,7 +869,7 @@ fn do_auto_cd(
|
||||
report_shell_error(
|
||||
engine_state,
|
||||
&ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::PermissionDenied,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::PermissionDenied),
|
||||
span,
|
||||
PathBuf::from(path),
|
||||
"Cannot change directory",
|
||||
|
@ -134,7 +134,7 @@ fn byte_stream_to_bits(stream: ByteStream, head: Span) -> ByteStream {
|
||||
let mut byte = [0];
|
||||
if reader
|
||||
.read(&mut byte[..])
|
||||
.map_err(|err| IoError::new(err.kind(), head, None))?
|
||||
.map_err(|err| IoError::new(err, head, None))?
|
||||
> 0
|
||||
{
|
||||
// Format the byte as bits
|
||||
|
@ -107,14 +107,14 @@ impl Command for Do {
|
||||
let mut buf = Vec::new();
|
||||
stdout.read_to_end(&mut buf).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not read stdout to end",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
})?;
|
||||
Ok::<_, ShellError>(buf)
|
||||
})
|
||||
.map_err(|err| IoError::new(err.kind(), head, None))
|
||||
.map_err(|err| IoError::new(err, head, None))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
@ -126,7 +126,7 @@ impl Command for Do {
|
||||
let mut buf = String::new();
|
||||
stderr
|
||||
.read_to_string(&mut buf)
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
buf
|
||||
}
|
||||
};
|
||||
|
@ -88,13 +88,19 @@ apparent the next time `nu` is next launched with that plugin registry file.
|
||||
let filename_expanded = nu_path::locate_in_dirs(&filename.item, &cwd, || {
|
||||
get_plugin_dirs(engine_state, stack)
|
||||
})
|
||||
.map_err(|err| IoError::new(err.kind(), filename.span, PathBuf::from(filename.item)))?;
|
||||
.map_err(|err| {
|
||||
IoError::new(
|
||||
err.not_found_as(NotFound::File),
|
||||
filename.span,
|
||||
PathBuf::from(filename.item),
|
||||
)
|
||||
})?;
|
||||
|
||||
let shell_expanded = shell
|
||||
.as_ref()
|
||||
.map(|s| {
|
||||
nu_path::canonicalize_with(&s.item, &cwd)
|
||||
.map_err(|err| IoError::new(err.kind(), s.span, None))
|
||||
.map_err(|err| IoError::new(err, s.span, None))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
#[allow(deprecated)]
|
||||
use nu_engine::{command_prelude::*, current_dir};
|
||||
use nu_protocol::{PluginRegistryFile, engine::StateWorkingSet, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
PluginRegistryFile,
|
||||
engine::StateWorkingSet,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
path::PathBuf,
|
||||
@ -46,12 +50,12 @@ pub(crate) fn read_plugin_file(
|
||||
if fs::metadata(&plugin_registry_file_path).is_ok_and(|m| m.len() > 0) {
|
||||
PluginRegistryFile::read_from(
|
||||
File::open(&plugin_registry_file_path)
|
||||
.map_err(|err| IoError::new(err.kind(), file_span, plugin_registry_file_path))?,
|
||||
.map_err(|err| IoError::new(err, file_span, plugin_registry_file_path))?,
|
||||
Some(file_span),
|
||||
)
|
||||
} else if let Some(path) = custom_path {
|
||||
Err(ShellError::Io(IoError::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
path.span,
|
||||
PathBuf::from(&path.item),
|
||||
)))
|
||||
@ -75,9 +79,8 @@ pub(crate) fn modify_plugin_file(
|
||||
// Try to read the plugin file if it exists
|
||||
let mut contents = if fs::metadata(&plugin_registry_file_path).is_ok_and(|m| m.len() > 0) {
|
||||
PluginRegistryFile::read_from(
|
||||
File::open(&plugin_registry_file_path).map_err(|err| {
|
||||
IoError::new(err.kind(), file_span, plugin_registry_file_path.clone())
|
||||
})?,
|
||||
File::open(&plugin_registry_file_path)
|
||||
.map_err(|err| IoError::new(err, file_span, plugin_registry_file_path.clone()))?,
|
||||
Some(file_span),
|
||||
)?
|
||||
} else {
|
||||
@ -90,7 +93,7 @@ pub(crate) fn modify_plugin_file(
|
||||
// Save the modified file on success
|
||||
contents.write_to(
|
||||
File::create(&plugin_registry_file_path)
|
||||
.map_err(|err| IoError::new(err.kind(), file_span, plugin_registry_file_path))?,
|
||||
.map_err(|err| IoError::new(err, file_span, plugin_registry_file_path))?,
|
||||
Some(span),
|
||||
)?;
|
||||
|
||||
|
@ -77,7 +77,7 @@ impl Command for BytesEndsWith {
|
||||
Ok(&[]) => break,
|
||||
Ok(buf) => buf,
|
||||
Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
|
||||
Err(e) => return Err(IoError::new(e.kind(), span, None).into()),
|
||||
Err(e) => return Err(IoError::new(e, span, None).into()),
|
||||
};
|
||||
let len = buf.len();
|
||||
if len >= cap {
|
||||
|
@ -72,7 +72,7 @@ impl Command for BytesStartsWith {
|
||||
reader
|
||||
.take(pattern.len() as u64)
|
||||
.read_to_end(&mut start)
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
|
||||
Ok(Value::bool(start == pattern, head).into_pipeline_data())
|
||||
} else {
|
||||
|
@ -41,12 +41,11 @@ impl SQLiteDatabase {
|
||||
}
|
||||
|
||||
pub fn try_from_path(path: &Path, span: Span, signals: Signals) -> Result<Self, ShellError> {
|
||||
let mut file =
|
||||
File::open(path).map_err(|e| IoError::new(e.kind(), span, PathBuf::from(path)))?;
|
||||
let mut file = File::open(path).map_err(|e| IoError::new(e, span, PathBuf::from(path)))?;
|
||||
|
||||
let mut buf: [u8; 16] = [0; 16];
|
||||
file.read_exact(&mut buf)
|
||||
.map_err(|e| ShellError::Io(IoError::new(e.kind(), span, PathBuf::from(path))))
|
||||
.map_err(|e| ShellError::Io(IoError::new(e, span, PathBuf::from(path))))
|
||||
.and_then(|_| {
|
||||
if buf == SQLITE_MAGIC_BYTES {
|
||||
Ok(SQLiteDatabase::new(path, signals))
|
||||
|
2
crates/nu-command/src/env/config/config_.rs
vendored
2
crates/nu-command/src/env/config/config_.rs
vendored
@ -115,7 +115,7 @@ pub(super) fn start_editor(
|
||||
|
||||
let child = child.map_err(|err| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
err,
|
||||
call.head,
|
||||
None,
|
||||
"Could not spawn foreground child",
|
||||
|
@ -59,7 +59,7 @@ impl Command for ConfigReset {
|
||||
));
|
||||
if let Err(err) = std::fs::rename(nu_config.clone(), &backup_path) {
|
||||
return Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
err.kind().not_found_as(NotFound::Directory),
|
||||
err.not_found_as(NotFound::Directory),
|
||||
span,
|
||||
PathBuf::from(backup_path),
|
||||
"config.nu could not be backed up",
|
||||
@ -69,7 +69,7 @@ impl Command for ConfigReset {
|
||||
if let Ok(mut file) = std::fs::File::create(&nu_config) {
|
||||
if let Err(err) = writeln!(&mut file, "{config_file}") {
|
||||
return Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
err.kind().not_found_as(NotFound::File),
|
||||
err.not_found_as(NotFound::File),
|
||||
span,
|
||||
PathBuf::from(nu_config),
|
||||
"config.nu could not be written to",
|
||||
@ -86,7 +86,7 @@ impl Command for ConfigReset {
|
||||
backup_path.push(format!("oldenv-{}.nu", Local::now().format("%F-%H-%M-%S"),));
|
||||
if let Err(err) = std::fs::rename(env_config.clone(), &backup_path) {
|
||||
return Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
err.kind().not_found_as(NotFound::Directory),
|
||||
err.not_found_as(NotFound::Directory),
|
||||
span,
|
||||
PathBuf::from(backup_path),
|
||||
"env.nu could not be backed up",
|
||||
@ -96,7 +96,7 @@ impl Command for ConfigReset {
|
||||
if let Ok(mut file) = std::fs::File::create(&env_config) {
|
||||
if let Err(err) = writeln!(&mut file, "{config_file}") {
|
||||
return Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
err.kind().not_found_as(NotFound::File),
|
||||
err.not_found_as(NotFound::File),
|
||||
span,
|
||||
PathBuf::from(env_config),
|
||||
"env.nu could not be written to",
|
||||
|
8
crates/nu-command/src/env/source_env.rs
vendored
8
crates/nu-command/src/env/source_env.rs
vendored
@ -2,7 +2,11 @@ use nu_engine::{
|
||||
command_prelude::*, find_in_dirs_env, get_dirs_var_from_call, get_eval_block_with_early_return,
|
||||
redirect_env,
|
||||
};
|
||||
use nu_protocol::{BlockId, engine::CommandType, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
BlockId,
|
||||
engine::CommandType,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Source a file for environment variables.
|
||||
@ -66,7 +70,7 @@ impl Command for SourceEnv {
|
||||
PathBuf::from(&path)
|
||||
} else {
|
||||
return Err(ShellError::Io(IoError::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
source_filename.span,
|
||||
PathBuf::from(source_filename.item),
|
||||
)));
|
||||
|
@ -53,7 +53,7 @@ impl Command for JobKill {
|
||||
|
||||
jobs.kill_and_remove(id).map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Failed to kill the requested job",
|
||||
nu_protocol::location!(),
|
||||
))
|
||||
|
@ -121,7 +121,7 @@ impl Command for JobSpawn {
|
||||
Err(err) => {
|
||||
jobs.remove_job(id);
|
||||
Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
err,
|
||||
call.head,
|
||||
None,
|
||||
"Failed to spawn thread for job",
|
||||
|
@ -3,7 +3,6 @@ use nu_protocol::{
|
||||
JobId,
|
||||
engine::{FrozenJob, Job, ThreadJob},
|
||||
process::check_ok,
|
||||
shell_error,
|
||||
};
|
||||
use nu_system::{ForegroundWaitStatus, kill_by_pid};
|
||||
|
||||
@ -123,7 +122,7 @@ fn unfreeze_job(
|
||||
if !thread_job.try_add_pid(pid) {
|
||||
kill_by_pid(pid.into()).map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"job was interrupted; could not kill foreground process",
|
||||
nu_protocol::location!(),
|
||||
))
|
||||
@ -163,7 +162,7 @@ fn unfreeze_job(
|
||||
Ok(ForegroundWaitStatus::Finished(status)) => check_ok(status, false, span),
|
||||
|
||||
Err(err) => Err(ShellError::Io(IoError::new_internal(
|
||||
shell_error::io::ErrorKind::Std(err.kind()),
|
||||
err,
|
||||
"Failed to unfreeze foreground process",
|
||||
nu_protocol::location!(),
|
||||
))),
|
||||
|
@ -77,7 +77,7 @@ impl Command for Cd {
|
||||
if let Ok(path) = nu_path::canonicalize_with(path_no_whitespace, &cwd) {
|
||||
if !path.is_dir() {
|
||||
return Err(shell_error::io::IoError::new(
|
||||
shell_error::io::ErrorKind::Std(
|
||||
shell_error::io::ErrorKind::from_std(
|
||||
std::io::ErrorKind::NotADirectory,
|
||||
),
|
||||
v.span,
|
||||
@ -106,7 +106,9 @@ impl Command for Cd {
|
||||
};
|
||||
if !path.is_dir() {
|
||||
return Err(shell_error::io::IoError::new(
|
||||
shell_error::io::ErrorKind::Std(std::io::ErrorKind::NotADirectory),
|
||||
shell_error::io::ErrorKind::from_std(
|
||||
std::io::ErrorKind::NotADirectory,
|
||||
),
|
||||
v.span,
|
||||
path,
|
||||
)
|
||||
@ -132,9 +134,12 @@ impl Command for Cd {
|
||||
stack.set_cwd(path)?;
|
||||
Ok(PipelineData::empty())
|
||||
}
|
||||
PermissionResult::PermissionDenied => {
|
||||
Err(IoError::new(std::io::ErrorKind::PermissionDenied, call.head, path).into())
|
||||
}
|
||||
PermissionResult::PermissionDenied => Err(IoError::new(
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::PermissionDenied),
|
||||
call.head,
|
||||
path,
|
||||
)
|
||||
.into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,10 @@ use nu_engine::glob_from;
|
||||
use nu_engine::{command_prelude::*, env::current_dir};
|
||||
use nu_glob::MatchOptions;
|
||||
use nu_path::{expand_path_with, expand_to_real_path};
|
||||
use nu_protocol::{DataSource, NuGlob, PipelineMetadata, Signals, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
DataSource, NuGlob, PipelineMetadata, Signals,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use pathdiff::diff_paths;
|
||||
use rayon::prelude::*;
|
||||
#[cfg(unix)]
|
||||
@ -252,7 +255,7 @@ fn ls_for_one_pattern(
|
||||
// it makes no sense to list an empty string.
|
||||
if path.item.as_ref().is_empty() {
|
||||
return Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::NotFound),
|
||||
path.span,
|
||||
PathBuf::from(path.item.to_string()),
|
||||
"empty string('') directory or file does not exist",
|
||||
@ -357,7 +360,7 @@ fn ls_for_one_pattern(
|
||||
let count = std::thread::available_parallelism()
|
||||
.map_err(|err| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
err,
|
||||
call_span,
|
||||
None,
|
||||
"Could not get available parallelism",
|
||||
@ -793,6 +796,7 @@ fn unix_time_to_local_date_time(secs: i64) -> Option<DateTime<Local>> {
|
||||
mod windows_helper {
|
||||
use super::*;
|
||||
|
||||
use nu_protocol::shell_error;
|
||||
use std::os::windows::prelude::OsStrExt;
|
||||
use windows::Win32::Foundation::FILETIME;
|
||||
use windows::Win32::Storage::FileSystem::{
|
||||
@ -928,7 +932,7 @@ mod windows_helper {
|
||||
Ok(find_data)
|
||||
}
|
||||
Err(e) => Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::Other,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
span,
|
||||
PathBuf::from(filename),
|
||||
format!("Could not read metadata: {e}"),
|
||||
@ -973,11 +977,11 @@ fn read_dir(
|
||||
let signals_clone = signals.clone();
|
||||
let items = f
|
||||
.read_dir()
|
||||
.map_err(|err| IoError::new(err.kind(), span, f.clone()))?
|
||||
.map_err(|err| IoError::new(err, span, f.clone()))?
|
||||
.map(move |d| {
|
||||
signals_clone.check(span)?;
|
||||
d.map(|r| r.path())
|
||||
.map_err(|err| IoError::new(err.kind(), span, f.clone()))
|
||||
.map_err(|err| IoError::new(err, span, f.clone()))
|
||||
.map_err(ShellError::from)
|
||||
});
|
||||
if !use_threads {
|
||||
|
@ -121,7 +121,7 @@ impl Command for Open {
|
||||
|
||||
if permission_denied(path) {
|
||||
let err = IoError::new(
|
||||
std::io::ErrorKind::PermissionDenied,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::PermissionDenied),
|
||||
arg_span,
|
||||
PathBuf::from(path),
|
||||
);
|
||||
@ -162,14 +162,18 @@ impl Command for Open {
|
||||
// At least under windows this check ensures that we don't get a
|
||||
// permission denied error on directories
|
||||
return Err(ShellError::Io(IoError::new(
|
||||
shell_error::io::ErrorKind::Std(std::io::ErrorKind::IsADirectory),
|
||||
#[allow(
|
||||
deprecated,
|
||||
reason = "we don't have a IsADirectory variant here, so we provide one"
|
||||
)]
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::IsADirectory),
|
||||
arg_span,
|
||||
PathBuf::from(path),
|
||||
)));
|
||||
}
|
||||
|
||||
let file = std::fs::File::open(path)
|
||||
.map_err(|err| IoError::new(err.kind(), arg_span, PathBuf::from(path)))?;
|
||||
.map_err(|err| IoError::new(err, arg_span, PathBuf::from(path)))?;
|
||||
|
||||
// No content_type by default - Is added later if no converter is found
|
||||
let stream = PipelineData::ByteStream(
|
||||
|
@ -304,7 +304,7 @@ fn rm(
|
||||
&& matches!(
|
||||
e,
|
||||
ShellError::Io(IoError {
|
||||
kind: shell_error::io::ErrorKind::Std(std::io::ErrorKind::NotFound),
|
||||
kind: shell_error::io::ErrorKind::Std(std::io::ErrorKind::NotFound, ..),
|
||||
..
|
||||
})
|
||||
))
|
||||
@ -420,7 +420,7 @@ fn rm(
|
||||
};
|
||||
|
||||
if let Err(e) = result {
|
||||
Err(ShellError::Io(IoError::new(e.kind(), span, f)))
|
||||
Err(ShellError::Io(IoError::new(e, span, f)))
|
||||
} else if verbose {
|
||||
let msg = if interactive && !confirmed {
|
||||
"not deleted"
|
||||
|
@ -130,7 +130,7 @@ impl Command for Save {
|
||||
io::copy(&mut tee, &mut io::stderr())
|
||||
}
|
||||
}
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -428,20 +428,24 @@ fn open_file(path: &Path, span: Span, append: bool) -> Result<File, ShellError>
|
||||
(true, true) => std::fs::OpenOptions::new()
|
||||
.append(true)
|
||||
.open(path)
|
||||
.map_err(|err| err.kind().into()),
|
||||
.map_err(|err| err.into()),
|
||||
_ => {
|
||||
// This is a temporary solution until `std::fs::File::create` is fixed on Windows (rust-lang/rust#134893)
|
||||
// A TOCTOU problem exists here, which may cause wrong error message to be shown
|
||||
#[cfg(target_os = "windows")]
|
||||
if path.is_dir() {
|
||||
Err(nu_protocol::shell_error::io::ErrorKind::Std(
|
||||
#[allow(
|
||||
deprecated,
|
||||
reason = "we don't get a IsADirectory error, so we need to provide it"
|
||||
)]
|
||||
Err(nu_protocol::shell_error::io::ErrorKind::from_std(
|
||||
std::io::ErrorKind::IsADirectory,
|
||||
))
|
||||
} else {
|
||||
std::fs::File::create(path).map_err(|err| err.kind().into())
|
||||
std::fs::File::create(path).map_err(|err| err.into())
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
std::fs::File::create(path).map_err(|err| err.kind().into())
|
||||
std::fs::File::create(path).map_err(|err| err.into())
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
#[allow(deprecated)]
|
||||
use nu_engine::{command_prelude::*, current_dir};
|
||||
use nu_protocol::{NuGlob, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
NuGlob,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
use uu_cp::{BackupMode, CopyMode, UpdateMode};
|
||||
|
||||
@ -198,7 +201,7 @@ impl Command for UCp {
|
||||
.collect();
|
||||
if exp_files.is_empty() {
|
||||
return Err(ShellError::Io(IoError::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
p.span,
|
||||
PathBuf::from(p.item.to_string()),
|
||||
)));
|
||||
|
@ -1,7 +1,10 @@
|
||||
#[allow(deprecated)]
|
||||
use nu_engine::{command_prelude::*, current_dir};
|
||||
use nu_path::expand_path_with;
|
||||
use nu_protocol::{NuGlob, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
NuGlob,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use std::{ffi::OsString, path::PathBuf};
|
||||
use uu_mv::{BackupMode, UpdateMode};
|
||||
|
||||
@ -139,7 +142,7 @@ impl Command for UMv {
|
||||
.collect();
|
||||
if exp_files.is_empty() {
|
||||
return Err(ShellError::Io(IoError::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
p.span,
|
||||
PathBuf::from(p.item.to_string()),
|
||||
)));
|
||||
|
@ -227,7 +227,7 @@ impl Command for UTouch {
|
||||
TouchError::ReferenceFileInaccessible(reference_path, io_err) => {
|
||||
let span = reference_span.expect("touch should've been given a reference file");
|
||||
ShellError::Io(IoError::new_with_additional_context(
|
||||
io_err.kind(),
|
||||
io_err,
|
||||
span,
|
||||
reference_path,
|
||||
"failed to read metadata",
|
||||
|
@ -86,7 +86,7 @@ impl Command for Watch {
|
||||
Ok(p) => p,
|
||||
Err(err) => {
|
||||
return Err(ShellError::Io(IoError::new(
|
||||
err.kind(),
|
||||
err,
|
||||
path_arg.span,
|
||||
PathBuf::from(path_no_whitespace),
|
||||
)));
|
||||
|
@ -37,7 +37,7 @@ pub fn empty(
|
||||
.bytes()
|
||||
.next()
|
||||
.transpose()
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?
|
||||
.map_err(|err| IoError::new(err, span, None))?
|
||||
.is_none();
|
||||
if negate {
|
||||
Ok(Value::bool(!is_empty, head).into_pipeline_data())
|
||||
|
@ -182,7 +182,7 @@ fn first_helper(
|
||||
let mut byte = [0u8];
|
||||
if reader
|
||||
.read(&mut byte)
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?
|
||||
.map_err(|err| IoError::new(err, span, None))?
|
||||
> 0
|
||||
{
|
||||
Ok(Value::int(byte[0] as i64, head).into_pipeline_data())
|
||||
|
@ -137,7 +137,7 @@ interleave
|
||||
}
|
||||
})
|
||||
.map(|_| ())
|
||||
.map_err(|err| IoError::new(err.kind(), head, None).into())
|
||||
.map_err(|err| IoError::new(err, head, None).into())
|
||||
})
|
||||
})?;
|
||||
|
||||
|
@ -166,7 +166,7 @@ impl Command for Last {
|
||||
let mut buf = VecDeque::with_capacity(rows + TAKE as usize);
|
||||
loop {
|
||||
let taken = std::io::copy(&mut (&mut reader).take(TAKE), &mut buf)
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
if buf.len() > rows {
|
||||
buf.drain(..(buf.len() - rows));
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
use nu_engine::{command_prelude::*, get_eval_block_with_early_return};
|
||||
#[cfg(feature = "os")]
|
||||
use nu_protocol::process::ChildPipe;
|
||||
#[cfg(test)]
|
||||
use nu_protocol::shell_error;
|
||||
use nu_protocol::{
|
||||
ByteStream, ByteStreamSource, OutDest, PipelineMetadata, Signals,
|
||||
byte_stream::copy_with_signals, engine::Closure, report_shell_error, shell_error::io::IoError,
|
||||
@ -440,7 +442,7 @@ fn spawn_tee(
|
||||
eval_block(PipelineData::ByteStream(stream, info.metadata))
|
||||
})
|
||||
.map_err(|err| {
|
||||
IoError::new_with_additional_context(err.kind(), info.span, None, "Could not spawn tee")
|
||||
IoError::new_with_additional_context(err, info.span, None, "Could not spawn tee")
|
||||
})?;
|
||||
|
||||
Ok(TeeThread { sender, thread })
|
||||
@ -481,13 +483,8 @@ fn copy_on_thread(
|
||||
Ok(())
|
||||
})
|
||||
.map_err(|err| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
span,
|
||||
None,
|
||||
"Could not spawn stderr copier",
|
||||
)
|
||||
.into()
|
||||
IoError::new_with_additional_context(err, span, None, "Could not spawn stderr copier")
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
@ -532,7 +529,7 @@ fn tee_forwards_errors_back_immediately() {
|
||||
let slow_input = (0..100).inspect(|_| std::thread::sleep(Duration::from_millis(1)));
|
||||
let iter = tee(slow_input, |_| {
|
||||
Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::Other,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
Span::test_data(),
|
||||
None,
|
||||
"test",
|
||||
@ -564,7 +561,7 @@ fn tee_waits_for_the_other_thread() {
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
waited_clone.store(true, Ordering::Relaxed);
|
||||
Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::Other,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
Span::test_data(),
|
||||
None,
|
||||
"test",
|
||||
|
@ -134,7 +134,7 @@ fn read_json_lines(
|
||||
.lines()
|
||||
.filter(|line| line.as_ref().is_ok_and(|line| !line.trim().is_empty()) || line.is_err())
|
||||
.map(move |line| {
|
||||
let line = line.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
let line = line.map_err(|err| IoError::new(err, span, None))?;
|
||||
if strict {
|
||||
convert_string_to_value_strict(&line, span)
|
||||
} else {
|
||||
|
@ -8,7 +8,7 @@ use std::{iter, sync::Arc};
|
||||
|
||||
fn make_csv_error(error: csv::Error, format_name: &str, head: Span) -> ShellError {
|
||||
if let csv::ErrorKind::Io(error) = error.kind() {
|
||||
IoError::new(error.kind(), head, None).into()
|
||||
IoError::new(error, head, None).into()
|
||||
} else {
|
||||
ShellError::GenericError {
|
||||
error: format!("Failed to generate {format_name} data"),
|
||||
|
@ -152,7 +152,7 @@ impl From<WriteError> for ShellError {
|
||||
help: None,
|
||||
inner: vec![],
|
||||
},
|
||||
WriteError::Io(err, span) => ShellError::Io(IoError::new(err.kind(), span, None)),
|
||||
WriteError::Io(err, span) => ShellError::Io(IoError::new(err, span, None)),
|
||||
WriteError::Shell(err) => *err,
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ impl Command for ToMsgpackz {
|
||||
serialize_types,
|
||||
)?;
|
||||
out.flush()
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
.map_err(|err| IoError::new(err, call.head, None))?;
|
||||
drop(out);
|
||||
|
||||
Ok(Value::binary(out_buf, call.head).into_pipeline_data())
|
||||
|
@ -55,13 +55,8 @@ impl Command for Source {
|
||||
let cwd = engine_state.cwd_as_string(Some(stack))?;
|
||||
let pb = std::path::PathBuf::from(block_id_name);
|
||||
let parent = pb.parent().unwrap_or(std::path::Path::new(""));
|
||||
let file_path = canonicalize_with(pb.as_path(), cwd).map_err(|err| {
|
||||
IoError::new(
|
||||
err.kind().not_found_as(NotFound::File),
|
||||
call.head,
|
||||
pb.clone(),
|
||||
)
|
||||
})?;
|
||||
let file_path = canonicalize_with(pb.as_path(), cwd)
|
||||
.map_err(|err| IoError::new(err.not_found_as(NotFound::File), call.head, pb.clone()))?;
|
||||
|
||||
// Note: We intentionally left out PROCESS_PATH since it's supposed to
|
||||
// to work like argv[0] in C, which is the name of the program being executed.
|
||||
|
@ -374,9 +374,7 @@ fn send_multipart_request(
|
||||
let mut builder = MultipartWriter::new();
|
||||
|
||||
let err = |e: std::io::Error| {
|
||||
ShellErrorOrRequestError::ShellError(
|
||||
IoError::new_with_additional_context(e.kind(), span, None, e).into(),
|
||||
)
|
||||
ShellErrorOrRequestError::ShellError(IoError::new(e, span, None).into())
|
||||
};
|
||||
|
||||
for (col, val) in val.into_owned() {
|
||||
@ -466,12 +464,7 @@ fn send_cancellable_request(
|
||||
let _ = tx.send(ret); // may fail if the user has cancelled the operation
|
||||
})
|
||||
.map_err(|err| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
span,
|
||||
None,
|
||||
"Could not spawn HTTP requester",
|
||||
)
|
||||
IoError::new_with_additional_context(err, span, None, "Could not spawn HTTP requester")
|
||||
})
|
||||
.map_err(ShellError::from)?;
|
||||
|
||||
@ -529,12 +522,7 @@ fn send_cancellable_request_bytes(
|
||||
let _ = tx.send(ret);
|
||||
})
|
||||
.map_err(|err| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
span,
|
||||
None,
|
||||
"Could not spawn HTTP requester",
|
||||
)
|
||||
IoError::new_with_additional_context(err, span, None, "Could not spawn HTTP requester")
|
||||
})
|
||||
.map_err(ShellError::from)?;
|
||||
|
||||
@ -685,7 +673,7 @@ fn handle_response_error(span: Span, requested_url: &str, response_err: Error) -
|
||||
break 'io generic_network_failure();
|
||||
};
|
||||
|
||||
ShellError::Io(IoError::new(io_error.kind(), span, None))
|
||||
ShellError::Io(IoError::new(io_error, span, None))
|
||||
}
|
||||
_ => generic_network_failure(),
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ fn get_free_port(
|
||||
}
|
||||
|
||||
Err(IoError::new_with_additional_context(
|
||||
last_err.expect("range not empty, validated before").kind(),
|
||||
last_err.expect("range not empty, validated before"),
|
||||
range_span,
|
||||
None,
|
||||
"Every port has been tried, but no valid one was found",
|
||||
|
@ -153,7 +153,7 @@ fn exists(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||
Value::bool(
|
||||
match exists {
|
||||
Ok(exists) => exists,
|
||||
Err(err) => return Value::error(IoError::new(err.kind(), span, path).into(), span),
|
||||
Err(err) => return Value::error(IoError::new(err, span, path).into(), span),
|
||||
},
|
||||
span,
|
||||
)
|
||||
|
@ -1,6 +1,9 @@
|
||||
use nu_engine::command_prelude::*;
|
||||
use nu_path::expand_path_with;
|
||||
use nu_protocol::{engine::StateWorkingSet, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
engine::StateWorkingSet,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PathSelf;
|
||||
@ -56,7 +59,7 @@ impl Command for PathSelf {
|
||||
let cwd = working_set.permanent_state.cwd(None)?;
|
||||
let current_file = working_set.files.top().ok_or_else(|| {
|
||||
IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
call.head,
|
||||
None,
|
||||
"Couldn't find current file",
|
||||
@ -67,7 +70,7 @@ impl Command for PathSelf {
|
||||
let dir = expand_path_with(
|
||||
current_file.parent().ok_or_else(|| {
|
||||
IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
call.head,
|
||||
current_file.to_owned(),
|
||||
"Couldn't find current file's parent.",
|
||||
|
@ -108,7 +108,7 @@ fn path_type(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||
match path.symlink_metadata() {
|
||||
Ok(metadata) => Value::string(get_file_type(&metadata), span),
|
||||
Err(err) if err.kind() == io::ErrorKind::NotFound => Value::nothing(span),
|
||||
Err(err) => Value::error(IoError::new(err.kind(), span, None).into(), span),
|
||||
Err(err) => Value::error(IoError::new(err, span, None).into(), span),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ impl FileInfo {
|
||||
long,
|
||||
})
|
||||
}
|
||||
Err(e) => Err(IoError::new(e.kind(), tag, path).into()),
|
||||
Err(e) => Err(IoError::new(e, tag, path).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use crossterm::{
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use nu_engine::command_prelude::*;
|
||||
use nu_protocol::shell_error::io::IoError;
|
||||
use nu_protocol::shell_error::{self, io::IoError};
|
||||
|
||||
use std::{io::Write, time::Duration};
|
||||
|
||||
@ -116,7 +116,9 @@ impl Command for Input {
|
||||
crossterm::terminal::disable_raw_mode()
|
||||
.map_err(&from_io_error)?;
|
||||
return Err(IoError::new(
|
||||
std::io::ErrorKind::Interrupted,
|
||||
shell_error::io::ErrorKind::from_std(
|
||||
std::io::ErrorKind::Interrupted,
|
||||
),
|
||||
call.head,
|
||||
None,
|
||||
)
|
||||
@ -156,7 +158,7 @@ impl Command for Input {
|
||||
terminal::Clear(ClearType::CurrentLine),
|
||||
cursor::MoveToColumn(0),
|
||||
)
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
.map_err(|err| IoError::new(err, call.head, None))?;
|
||||
if let Some(prompt) = &prompt {
|
||||
execute!(std::io::stdout(), Print(prompt.to_string()))
|
||||
.map_err(&from_io_error)?;
|
||||
|
@ -84,7 +84,7 @@ There are 4 `key_type` variants:
|
||||
let add_raw = call.has_flag(engine_state, stack, "raw")?;
|
||||
let config = engine_state.get_config();
|
||||
|
||||
terminal::enable_raw_mode().map_err(|err| IoError::new(err.kind(), head, None))?;
|
||||
terminal::enable_raw_mode().map_err(|err| IoError::new(err, head, None))?;
|
||||
|
||||
if config.use_kitty_protocol {
|
||||
if let Ok(false) = crossterm::terminal::supports_keyboard_enhancement() {
|
||||
@ -123,7 +123,7 @@ There are 4 `key_type` variants:
|
||||
})?;
|
||||
let event = parse_event(head, &event, &event_type_filter, add_raw);
|
||||
if let Some(event) = event {
|
||||
terminal::disable_raw_mode().map_err(|err| IoError::new(err.kind(), head, None))?;
|
||||
terminal::disable_raw_mode().map_err(|err| IoError::new(err, head, None))?;
|
||||
if config.use_kitty_protocol {
|
||||
let _ = execute!(
|
||||
std::io::stdout(),
|
||||
@ -230,17 +230,17 @@ impl EventTypeFilter {
|
||||
fn enable_events(&self, span: Span) -> Result<DeferredConsoleRestore, ShellError> {
|
||||
if self.listen_mouse {
|
||||
crossterm::execute!(stdout(), EnableMouseCapture)
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
}
|
||||
|
||||
if self.listen_paste {
|
||||
crossterm::execute!(stdout(), EnableBracketedPaste)
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
}
|
||||
|
||||
if self.listen_focus {
|
||||
crossterm::execute!(stdout(), crossterm::event::EnableFocusChange)
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
}
|
||||
|
||||
Ok(DeferredConsoleRestore {
|
||||
|
@ -142,12 +142,7 @@ impl Command for InputList {
|
||||
.report(false)
|
||||
.interact_on_opt(&Term::stderr())
|
||||
.map_err(|dialoguer::Error::IO(err)| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
call.head,
|
||||
None,
|
||||
INTERACT_ERROR,
|
||||
)
|
||||
IoError::new_with_additional_context(err, call.head, None, INTERACT_ERROR)
|
||||
})?,
|
||||
)
|
||||
} else if fuzzy {
|
||||
@ -164,12 +159,7 @@ impl Command for InputList {
|
||||
.report(false)
|
||||
.interact_on_opt(&Term::stderr())
|
||||
.map_err(|dialoguer::Error::IO(err)| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
call.head,
|
||||
None,
|
||||
INTERACT_ERROR,
|
||||
)
|
||||
IoError::new_with_additional_context(err, call.head, None, INTERACT_ERROR)
|
||||
})?,
|
||||
)
|
||||
} else {
|
||||
@ -185,12 +175,7 @@ impl Command for InputList {
|
||||
.report(false)
|
||||
.interact_on_opt(&Term::stderr())
|
||||
.map_err(|dialoguer::Error::IO(err)| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
call.head,
|
||||
None,
|
||||
INTERACT_ERROR,
|
||||
)
|
||||
IoError::new_with_additional_context(err, call.head, None, INTERACT_ERROR)
|
||||
})?,
|
||||
)
|
||||
};
|
||||
|
@ -99,19 +99,17 @@ The `prefix` is not included in the output."
|
||||
let prefix = prefix.unwrap_or_default();
|
||||
let terminator: Option<Vec<u8>> = call.get_flag(engine_state, stack, "terminator")?;
|
||||
|
||||
crossterm::terminal::enable_raw_mode()
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
crossterm::terminal::enable_raw_mode().map_err(|err| IoError::new(err, call.head, None))?;
|
||||
scopeguard::defer! {
|
||||
let _ = crossterm::terminal::disable_raw_mode();
|
||||
}
|
||||
|
||||
// clear terminal events
|
||||
while crossterm::event::poll(Duration::from_secs(0))
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?
|
||||
.map_err(|err| IoError::new(err, call.head, None))?
|
||||
{
|
||||
// If there's an event, read it to remove it from the queue
|
||||
let _ = crossterm::event::read()
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
let _ = crossterm::event::read().map_err(|err| IoError::new(err, call.head, None))?;
|
||||
}
|
||||
|
||||
let mut b = [0u8; 1];
|
||||
@ -122,17 +120,17 @@ The `prefix` is not included in the output."
|
||||
let mut stdout = std::io::stdout().lock();
|
||||
stdout
|
||||
.write_all(&query)
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
.map_err(|err| IoError::new(err, call.head, None))?;
|
||||
stdout
|
||||
.flush()
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
.map_err(|err| IoError::new(err, call.head, None))?;
|
||||
}
|
||||
|
||||
// Validate and skip prefix
|
||||
for bc in prefix {
|
||||
stdin
|
||||
.read_exact(&mut b)
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
.map_err(|err| IoError::new(err, call.head, None))?;
|
||||
if b[0] != bc {
|
||||
return Err(ShellError::GenericError {
|
||||
error: "Input did not begin with expected sequence".into(),
|
||||
@ -151,7 +149,7 @@ The `prefix` is not included in the output."
|
||||
loop {
|
||||
stdin
|
||||
.read_exact(&mut b)
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
.map_err(|err| IoError::new(err, call.head, None))?;
|
||||
|
||||
if b[0] == CTRL_C {
|
||||
return Err(ShellError::InterruptedByUser {
|
||||
@ -173,7 +171,7 @@ The `prefix` is not included in the output."
|
||||
loop {
|
||||
stdin
|
||||
.read_exact(&mut b)
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
.map_err(|err| IoError::new(err, call.head, None))?;
|
||||
|
||||
if b[0] == CTRL_C {
|
||||
break;
|
||||
|
@ -255,7 +255,7 @@ fn parse_file_script(
|
||||
match std::fs::read(path) {
|
||||
Ok(contents) => parse_script(working_set, Some(&filename), &contents, is_debug, call_head),
|
||||
Err(err) => Err(ShellError::Io(IoError::new(
|
||||
err.kind().not_found_as(NotFound::File),
|
||||
err.not_found_as(NotFound::File),
|
||||
path_span,
|
||||
PathBuf::from(path),
|
||||
))),
|
||||
|
@ -93,7 +93,7 @@ fn registry_query(
|
||||
let reg_hive = get_reg_hive(engine_state, stack, call)?;
|
||||
let reg_key = reg_hive
|
||||
.open_subkey(registry_key.item)
|
||||
.map_err(|err| IoError::new(err.kind(), *registry_key_span, None))?;
|
||||
.map_err(|err| IoError::new(err, *registry_key_span, None))?;
|
||||
|
||||
if registry_value.is_none() {
|
||||
let mut reg_values = vec![];
|
||||
|
@ -205,11 +205,11 @@ impl Command for External {
|
||||
let stderr = stack.stderr();
|
||||
let merged_stream = if matches!(stdout, OutDest::Pipe) && matches!(stderr, OutDest::Pipe) {
|
||||
let (reader, writer) =
|
||||
os_pipe::pipe().map_err(|err| IoError::new(err.kind(), call.head, None))?;
|
||||
os_pipe::pipe().map_err(|err| IoError::new(err, call.head, None))?;
|
||||
command.stdout(
|
||||
writer
|
||||
.try_clone()
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?,
|
||||
.map_err(|err| IoError::new(err, call.head, None))?,
|
||||
);
|
||||
command.stderr(writer);
|
||||
Some(reader)
|
||||
@ -220,8 +220,7 @@ impl Command for External {
|
||||
command.stdout(Stdio::null());
|
||||
} else {
|
||||
command.stdout(
|
||||
Stdio::try_from(stdout)
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?,
|
||||
Stdio::try_from(stdout).map_err(|err| IoError::new(err, call.head, None))?,
|
||||
);
|
||||
}
|
||||
|
||||
@ -231,8 +230,7 @@ impl Command for External {
|
||||
command.stderr(Stdio::null());
|
||||
} else {
|
||||
command.stderr(
|
||||
Stdio::try_from(stderr)
|
||||
.map_err(|err| IoError::new(err.kind(), call.head, None))?,
|
||||
Stdio::try_from(stderr).map_err(|err| IoError::new(err, call.head, None))?,
|
||||
);
|
||||
}
|
||||
|
||||
@ -280,7 +278,7 @@ impl Command for External {
|
||||
|
||||
let mut child = child.map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not spawn foreground child",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
@ -290,7 +288,7 @@ impl Command for External {
|
||||
if !thread_job.try_add_pid(child.pid()) {
|
||||
kill_by_pid(child.pid().into()).map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not spawn external stdin worker",
|
||||
nu_protocol::location!(),
|
||||
))
|
||||
@ -310,7 +308,7 @@ impl Command for External {
|
||||
})
|
||||
.map_err(|err| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
err,
|
||||
call.head,
|
||||
None,
|
||||
"Could not spawn external stdin worker",
|
||||
@ -498,7 +496,7 @@ fn write_pipeline_data(
|
||||
} else if let PipelineData::Value(Value::Binary { val, .. }, ..) = data {
|
||||
writer.write_all(&val).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not write pipeline data",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
@ -518,7 +516,7 @@ fn write_pipeline_data(
|
||||
let bytes = value.coerce_into_binary()?;
|
||||
writer.write_all(&bytes).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not write pipeline data",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
|
@ -518,7 +518,7 @@ fn pretty_hex_stream(stream: ByteStream, span: Span) -> ByteStream {
|
||||
(&mut reader)
|
||||
.take(cfg.width as u64)
|
||||
.read_to_end(&mut read_buf)
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
|
||||
if !read_buf.is_empty() {
|
||||
nu_pretty_hex::hex_write(&mut write_buf, &read_buf, cfg, Some(true))
|
||||
|
@ -60,5 +60,5 @@ fn self_path_runtime() {
|
||||
fn self_path_repl() {
|
||||
let actual = nu!("const foo = path self; $foo");
|
||||
assert!(!actual.status.success());
|
||||
assert!(actual.err.contains("nu::shell::io::not_found"));
|
||||
assert!(actual.err.contains("nu::shell::io::file_not_found"));
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ use nu_test_support::playground::Playground;
|
||||
use rstest::rstest;
|
||||
#[cfg(not(windows))]
|
||||
use std::fs;
|
||||
#[cfg(windows)]
|
||||
use std::{fs::OpenOptions, os::windows::fs::OpenOptionsExt};
|
||||
|
||||
#[test]
|
||||
fn removes_a_file() {
|
||||
@ -562,3 +564,26 @@ fn rm_with_tilde() {
|
||||
assert!(!files_exist_at(&["~tilde"], dirs.test()));
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn rm_already_in_use() {
|
||||
Playground::setup("rm_already_in_use", |dirs, sandbox| {
|
||||
sandbox.with_files(&[EmptyFile("i_will_be_used.txt")]);
|
||||
|
||||
let file_path = dirs.root().join("rm_already_in_use/i_will_be_used.txt");
|
||||
let _file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(false)
|
||||
.share_mode(0) // deny all sharing
|
||||
.open(file_path)
|
||||
.unwrap();
|
||||
|
||||
let outcome = nu!(
|
||||
cwd: dirs.root(),
|
||||
"rm rm_already_in_use/i_will_be_used.txt"
|
||||
);
|
||||
|
||||
assert!(outcome.err.contains("nu::shell::io::already_in_use"));
|
||||
})
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use nu_protocol::{
|
||||
ShellError, Span, Type, Value, VarId,
|
||||
ast::Expr,
|
||||
engine::{Call, EngineState, Stack, StateWorkingSet},
|
||||
shell_error::io::{ErrorKindExt, IoError, NotFound},
|
||||
shell_error::io::{IoError, IoErrorExt, NotFound},
|
||||
};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
@ -221,7 +221,7 @@ pub fn current_dir(engine_state: &EngineState, stack: &Stack) -> Result<PathBuf,
|
||||
// be an absolute path already.
|
||||
canonicalize_with(&cwd, ".").map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal_with_path(
|
||||
err.kind().not_found_as(NotFound::Directory),
|
||||
err.not_found_as(NotFound::Directory),
|
||||
"Could not canonicalize current dir",
|
||||
nu_protocol::location!(),
|
||||
PathBuf::from(cwd),
|
||||
@ -241,7 +241,7 @@ pub fn current_dir_const(working_set: &StateWorkingSet) -> Result<PathBuf, Shell
|
||||
// be an absolute path already.
|
||||
canonicalize_with(&cwd, ".").map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal_with_path(
|
||||
err.kind().not_found_as(NotFound::Directory),
|
||||
err.not_found_as(NotFound::Directory),
|
||||
"Could not canonicalize current dir",
|
||||
nu_protocol::location!(),
|
||||
PathBuf::from(cwd),
|
||||
|
@ -1529,7 +1529,7 @@ fn open_file(ctx: &EvalContext<'_>, path: &Value, append: bool) -> Result<Arc<Fi
|
||||
let file = options
|
||||
.create(true)
|
||||
.open(&path_expanded)
|
||||
.map_err(|err| IoError::new(err.kind(), path.span(), path_expanded))?;
|
||||
.map_err(|err| IoError::new(err, path.span(), path_expanded))?;
|
||||
Ok(Arc::new(file))
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ pub fn glob_from(
|
||||
}
|
||||
Ok(p) => p,
|
||||
Err(err) => {
|
||||
return Err(IoError::new(err.kind(), pattern_span, path).into());
|
||||
return Err(IoError::new(err, pattern_span, path).into());
|
||||
}
|
||||
};
|
||||
(path.parent().map(|parent| parent.to_path_buf()), path)
|
||||
|
@ -87,7 +87,7 @@ impl CommunicationMode {
|
||||
.and_then(|name| ListenerOptions::new().name(name).create_sync())
|
||||
.map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
format!(
|
||||
"Could not interpret local socket name {:?}",
|
||||
name.to_string_lossy()
|
||||
@ -117,7 +117,7 @@ impl CommunicationMode {
|
||||
.and_then(|name| ls::Stream::connect(name))
|
||||
.map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
format!(
|
||||
"Could not interpret local socket name {:?}",
|
||||
name.to_string_lossy()
|
||||
@ -190,7 +190,7 @@ impl PreparedServerCommunication {
|
||||
.set_nonblocking(ListenerNonblockingMode::Accept)
|
||||
.map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not set non-blocking mode accept for listener",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
@ -204,7 +204,7 @@ impl PreparedServerCommunication {
|
||||
// good measure. Had an issue without this on macOS.
|
||||
stream.set_nonblocking(false).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not disable non-blocking mode for listener",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
@ -217,7 +217,7 @@ impl PreparedServerCommunication {
|
||||
// `WouldBlock` is ok, just means it's not ready yet, but some other
|
||||
// kind of error should be reported
|
||||
return Err(ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Accepting new data from listener failed",
|
||||
nu_protocol::location!(),
|
||||
)));
|
||||
|
@ -82,7 +82,7 @@ where
|
||||
fn flush(&self) -> Result<(), ShellError> {
|
||||
self.0.lock().flush().map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"PluginWrite could not flush",
|
||||
nu_protocol::location!(),
|
||||
))
|
||||
@ -112,7 +112,7 @@ where
|
||||
})?;
|
||||
lock.flush().map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"PluginWrite could not flush",
|
||||
nu_protocol::location!(),
|
||||
))
|
||||
@ -340,7 +340,7 @@ where
|
||||
writer.write_all(std::iter::from_fn(move || match reader.read(buf) {
|
||||
Ok(0) => None,
|
||||
Ok(len) => Some(Ok(buf[..len].to_vec())),
|
||||
Err(err) => Some(Err(ShellError::from(IoError::new(err.kind(), span, None)))),
|
||||
Err(err) => Some(Err(ShellError::from(IoError::new(err, span, None)))),
|
||||
}))?;
|
||||
Ok(())
|
||||
}
|
||||
@ -368,7 +368,7 @@ where
|
||||
})
|
||||
.map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not spawn plugin stream background writer",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
|
@ -246,7 +246,7 @@ fn read_pipeline_data_byte_stream() -> Result<(), ShellError> {
|
||||
ByteStreamSource::Read(mut read) => {
|
||||
let mut buf = Vec::new();
|
||||
read.read_to_end(&mut buf)
|
||||
.map_err(|err| IoError::new(err.kind(), test_span, None))?;
|
||||
.map_err(|err| IoError::new(err, test_span, None))?;
|
||||
let iter = buf.chunks_exact(out_pattern.len());
|
||||
assert_eq!(iter.len(), iterations);
|
||||
for chunk in iter {
|
||||
|
@ -1,5 +1,8 @@
|
||||
use nu_plugin_protocol::{PluginInput, PluginOutput};
|
||||
use nu_protocol::{ShellError, location, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
ShellError, location,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{Encoder, PluginEncoder};
|
||||
@ -28,7 +31,7 @@ impl Encoder<PluginInput> for JsonSerializer {
|
||||
serde_json::to_writer(&mut *writer, plugin_input).map_err(json_encode_err)?;
|
||||
writer.write_all(b"\n").map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Failed to write final line break",
|
||||
location!(),
|
||||
))
|
||||
@ -55,7 +58,7 @@ impl Encoder<PluginOutput> for JsonSerializer {
|
||||
serde_json::to_writer(&mut *writer, plugin_output).map_err(json_encode_err)?;
|
||||
writer.write_all(b"\n").map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"JsonSerializer could not encode linebreak",
|
||||
nu_protocol::location!(),
|
||||
))
|
||||
@ -77,7 +80,7 @@ impl Encoder<PluginOutput> for JsonSerializer {
|
||||
fn json_encode_err(err: serde_json::Error) -> ShellError {
|
||||
if err.is_io() {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.io_error_kind().expect("is io"),
|
||||
shell_error::io::ErrorKind::from_std(err.io_error_kind().expect("is io")),
|
||||
"Could not encode with json",
|
||||
nu_protocol::location!(),
|
||||
))
|
||||
@ -94,7 +97,7 @@ fn json_decode_err<T>(err: serde_json::Error) -> Result<Option<T>, ShellError> {
|
||||
Ok(None)
|
||||
} else if err.is_io() {
|
||||
Err(ShellError::Io(IoError::new_internal(
|
||||
err.io_error_kind().expect("is io"),
|
||||
shell_error::io::ErrorKind::from_std(err.io_error_kind().expect("is io")),
|
||||
"Could not decode with json",
|
||||
nu_protocol::location!(),
|
||||
)))
|
||||
|
@ -1,7 +1,10 @@
|
||||
use std::io::ErrorKind;
|
||||
|
||||
use nu_plugin_protocol::{PluginInput, PluginOutput};
|
||||
use nu_protocol::{ShellError, shell_error::io::IoError};
|
||||
use nu_protocol::{
|
||||
ShellError,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{Encoder, PluginEncoder};
|
||||
@ -66,7 +69,7 @@ fn rmp_encode_err(err: rmp_serde::encode::Error) -> ShellError {
|
||||
// I/O error
|
||||
ShellError::Io(IoError::new_internal(
|
||||
// TODO: get a better kind here
|
||||
std::io::ErrorKind::Other,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
"Could not encode with rmp",
|
||||
nu_protocol::location!(),
|
||||
))
|
||||
@ -92,7 +95,7 @@ fn rmp_decode_err<T>(err: rmp_serde::decode::Error) -> Result<Option<T>, ShellEr
|
||||
// I/O error
|
||||
Err(ShellError::Io(IoError::new_internal(
|
||||
// TODO: get a better kind here
|
||||
std::io::ErrorKind::Other,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
"Could not decode with rmp",
|
||||
nu_protocol::location!(),
|
||||
)))
|
||||
|
@ -379,7 +379,7 @@ macro_rules! generate_tests {
|
||||
.with_help("some help")
|
||||
.with_label("msg", Span::new(2, 30))
|
||||
.with_inner(ShellError::Io(IoError::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::NotFound),
|
||||
Span::test_data(),
|
||||
None,
|
||||
)));
|
||||
|
@ -20,6 +20,7 @@ use nu_protocol::{
|
||||
Spanned, Value,
|
||||
ast::{Math, Operator},
|
||||
engine::Closure,
|
||||
shell_error,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
@ -87,7 +88,7 @@ fn manager_consume_all_exits_after_streams_and_interfaces_are_dropped() -> Resul
|
||||
|
||||
fn test_io_error() -> ShellError {
|
||||
ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::Other,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
Span::test_data(),
|
||||
None,
|
||||
"test io error",
|
||||
|
@ -190,11 +190,7 @@ impl PersistentPlugin {
|
||||
|
||||
// Start the plugin garbage collector
|
||||
let gc = PluginGc::new(mutable.gc_config.clone(), &self).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
"Could not start plugin gc",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
IoError::new_internal(err, "Could not start plugin gc", nu_protocol::location!())
|
||||
})?;
|
||||
|
||||
let pid = child.id();
|
||||
|
@ -66,7 +66,7 @@ pub(crate) fn spawn_fake_plugin(
|
||||
.spawn(move || manager.consume_all(output_read).expect("Plugin read error"))
|
||||
.map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
format!("Could not spawn fake plugin interface reader ({name})"),
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
@ -87,7 +87,7 @@ pub(crate) fn spawn_fake_plugin(
|
||||
})
|
||||
.map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
format!("Could not spawn fake plugin runner ({name})"),
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
|
@ -1048,7 +1048,7 @@ impl ForegroundGuard {
|
||||
// This should always succeed, frankly, but handle the error just in case
|
||||
setpgid(Pid::from_raw(0), Pid::from_raw(0)).map_err(|err| {
|
||||
nu_protocol::shell_error::io::IoError::new_internal(
|
||||
std::io::Error::from(err).kind(),
|
||||
std::io::Error::from(err),
|
||||
"Could not set pgid",
|
||||
nu_protocol::location!(),
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ use nu_plugin_protocol::{
|
||||
use nu_protocol::{
|
||||
BlockId, ByteStreamType, Config, CustomValue, IntoInterruptiblePipelineData, LabeledError,
|
||||
PipelineData, PluginSignature, ShellError, Signals, Span, Spanned, Value, VarId,
|
||||
engine::Closure,
|
||||
engine::Closure, shell_error,
|
||||
};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
@ -91,7 +91,7 @@ fn manager_consume_all_exits_after_streams_and_interfaces_are_dropped() -> Resul
|
||||
|
||||
fn test_io_error() -> ShellError {
|
||||
ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::Other,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
Span::test_data(),
|
||||
None,
|
||||
"test io error",
|
||||
|
@ -51,6 +51,7 @@ nix = { workspace = true, default-features = false, features = ["signal"] }
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
dirs-sys = { workspace = true }
|
||||
windows-sys = { workspace = true }
|
||||
windows = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["os"]
|
||||
|
@ -353,7 +353,7 @@ impl EngineState {
|
||||
|
||||
let cwd = self.cwd(Some(stack))?;
|
||||
std::env::set_current_dir(cwd).map_err(|err| {
|
||||
IoError::new_internal(err.kind(), "Could not set current dir", crate::location!())
|
||||
IoError::new_internal(err, "Could not set current dir", crate::location!())
|
||||
})?;
|
||||
|
||||
if let Some(config) = stack.config.take() {
|
||||
@ -546,7 +546,7 @@ impl EngineState {
|
||||
Ok(PluginRegistryFile::default())
|
||||
} else {
|
||||
Err(ShellError::Io(IoError::new_internal_with_path(
|
||||
err.kind(),
|
||||
err,
|
||||
"Failed to open plugin file",
|
||||
crate::location!(),
|
||||
PathBuf::from(plugin_path),
|
||||
@ -563,7 +563,7 @@ impl EngineState {
|
||||
// Write it to the same path
|
||||
let plugin_file = File::create(plugin_path.as_path()).map_err(|err| {
|
||||
IoError::new_internal_with_path(
|
||||
err.kind(),
|
||||
err,
|
||||
"Failed to write plugin file",
|
||||
crate::location!(),
|
||||
PathBuf::from(plugin_path),
|
||||
|
@ -143,11 +143,11 @@ impl LabeledError {
|
||||
/// [`ShellError`] implements `miette::Diagnostic`:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use nu_protocol::{ShellError, LabeledError, shell_error::io::IoError, Span};
|
||||
/// # use nu_protocol::{ShellError, LabeledError, shell_error::{self, io::IoError}, Span};
|
||||
/// #
|
||||
/// let error = LabeledError::from_diagnostic(
|
||||
/// &ShellError::Io(IoError::new_with_additional_context(
|
||||
/// std::io::ErrorKind::Other,
|
||||
/// shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
/// Span::test_data(),
|
||||
/// None,
|
||||
/// "some error"
|
||||
|
@ -38,7 +38,7 @@ use super::{ShellError, location::Location};
|
||||
///
|
||||
/// # let span = Span::test_data();
|
||||
/// let path = PathBuf::from("/some/missing/file");
|
||||
/// let error = IoError::new(std::io::ErrorKind::NotFound, span, path);
|
||||
/// let error = IoError::new(ErrorKind::FileNotFound, span, path);
|
||||
/// println!("Error: {:?}", error);
|
||||
/// ```
|
||||
///
|
||||
@ -47,7 +47,7 @@ use super::{ShellError, location::Location};
|
||||
/// # use nu_protocol::shell_error::io::{IoError, ErrorKind};
|
||||
// #
|
||||
/// let error = IoError::new_internal(
|
||||
/// std::io::ErrorKind::UnexpectedEof,
|
||||
/// ErrorKind::from_std(std::io::ErrorKind::UnexpectedEof),
|
||||
/// "Failed to read data from buffer",
|
||||
/// nu_protocol::location!()
|
||||
/// );
|
||||
@ -93,7 +93,7 @@ pub struct IoError {
|
||||
/// and is part of [`std::io::Error`].
|
||||
/// If a kind cannot be represented by it, consider adding a new variant to [`ErrorKind`].
|
||||
///
|
||||
/// Only in very rare cases should [`std::io::ErrorKind::Other`] be used, make sure you provide
|
||||
/// Only in very rare cases should [`std::io::ErrorKind::other()`] be used, make sure you provide
|
||||
/// `additional_context` to get useful errors in these cases.
|
||||
pub kind: ErrorKind,
|
||||
|
||||
@ -125,15 +125,63 @@ pub struct IoError {
|
||||
pub location: Option<String>,
|
||||
}
|
||||
|
||||
/// Prevents other crates from constructing certain enum variants directly.
|
||||
///
|
||||
/// This type is only used to block construction while still allowing pattern matching.
|
||||
/// It's not meant to be used for anything else.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
struct Sealed;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Diagnostic)]
|
||||
pub enum ErrorKind {
|
||||
Std(std::io::ErrorKind),
|
||||
/// [`std::io::ErrorKind`] from the standard library.
|
||||
///
|
||||
/// This variant wraps a standard library error kind and extends our own error enum with it.
|
||||
/// The hidden field prevents other crates, even our own, from constructing this directly.
|
||||
/// Most of the time, you already have a full [`std::io::Error`], so just pass that directly to
|
||||
/// [`IoError::new`] or [`IoError::new_with_additional_context`].
|
||||
/// This allows us to inspect the raw os error of `std::io::Error`s.
|
||||
///
|
||||
/// Matching is still easy:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use nu_protocol::shell_error::io::ErrorKind;
|
||||
/// #
|
||||
/// # let err_kind = ErrorKind::from_std(std::io::ErrorKind::NotFound);
|
||||
/// match err_kind {
|
||||
/// ErrorKind::Std(std::io::ErrorKind::NotFound, ..) => { /* ... */ }
|
||||
/// _ => {}
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If you want to provide an [`std::io::ErrorKind`] manually, use [`ErrorKind::from_std`].
|
||||
#[allow(private_interfaces)]
|
||||
Std(std::io::ErrorKind, Sealed),
|
||||
|
||||
NotAFile,
|
||||
|
||||
/// The file or directory is in use by another program.
|
||||
///
|
||||
/// On Windows, this maps to
|
||||
/// [`ERROR_SHARING_VIOLATION`](windows::Win32::Foundation::ERROR_SHARING_VIOLATION) and
|
||||
/// prevents access like deletion or modification.
|
||||
AlreadyInUse,
|
||||
|
||||
// use these variants in cases where we know precisely whether a file or directory was expected
|
||||
FileNotFound,
|
||||
DirectoryNotFound,
|
||||
}
|
||||
|
||||
impl ErrorKind {
|
||||
/// Construct an [`ErrorKind`] from a [`std::io::ErrorKind`] without a full [`std::io::Error`].
|
||||
///
|
||||
/// In most cases, you should use [`IoError::new`] and pass the full [`std::io::Error`] instead.
|
||||
/// This method is only meant for cases where we provide our own io error kinds.
|
||||
pub fn from_std(kind: std::io::ErrorKind) -> Self {
|
||||
Self::Std(kind, Sealed)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Error, Diagnostic)]
|
||||
#[error("{0}")]
|
||||
pub struct AdditionalContext(String);
|
||||
@ -237,10 +285,10 @@ impl IoError {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use nu_protocol::shell_error::io::IoError;
|
||||
/// use nu_protocol::shell_error::{self, io::IoError};
|
||||
///
|
||||
/// let error = IoError::new_internal(
|
||||
/// std::io::ErrorKind::UnexpectedEof,
|
||||
/// shell_error::io::ErrorKind::from_std(std::io::ErrorKind::UnexpectedEof),
|
||||
/// "Failed to read from buffer",
|
||||
/// nu_protocol::location!(),
|
||||
/// );
|
||||
@ -268,11 +316,11 @@ impl IoError {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use nu_protocol::shell_error::io::IoError;
|
||||
/// use nu_protocol::shell_error::{self, io::IoError};
|
||||
/// use std::path::PathBuf;
|
||||
///
|
||||
/// let error = IoError::new_internal_with_path(
|
||||
/// std::io::ErrorKind::NotFound,
|
||||
/// shell_error::io::ErrorKind::FileNotFound,
|
||||
/// "Could not find special file",
|
||||
/// nu_protocol::location!(),
|
||||
/// PathBuf::from("/some/file"),
|
||||
@ -297,14 +345,37 @@ impl IoError {
|
||||
///
|
||||
/// This method is particularly useful when you need to handle multiple I/O errors which all
|
||||
/// take the same span and path.
|
||||
/// Instead of calling `.map_err(|err| IoError::new(err.kind(), span, path))` every time, you
|
||||
/// Instead of calling `.map_err(|err| IoError::new(err, span, path))` every time, you
|
||||
/// can create the factory closure once and pass that into `.map_err`.
|
||||
pub fn factory<'p, P>(span: Span, path: P) -> impl Fn(std::io::Error) -> Self + use<'p, P>
|
||||
where
|
||||
P: Into<Option<&'p Path>>,
|
||||
{
|
||||
let path = path.into();
|
||||
move |err: std::io::Error| IoError::new(err.kind(), span, path.map(PathBuf::from))
|
||||
move |err: std::io::Error| IoError::new(err, span, path.map(PathBuf::from))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ErrorKind {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
(&err).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&std::io::Error> for ErrorKind {
|
||||
fn from(err: &std::io::Error) -> Self {
|
||||
#[cfg(windows)]
|
||||
if let Some(raw_os_error) = err.raw_os_error() {
|
||||
use windows::Win32::Foundation;
|
||||
|
||||
#[allow(clippy::single_match, reason = "in the future we can expand here")]
|
||||
match Foundation::WIN32_ERROR(raw_os_error as u32) {
|
||||
Foundation::ERROR_SHARING_VIOLATION => return ErrorKind::AlreadyInUse,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
ErrorKind::Std(err.kind(), Sealed)
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,7 +383,7 @@ impl StdError for IoError {}
|
||||
impl Display for IoError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self.kind {
|
||||
ErrorKind::Std(std::io::ErrorKind::NotFound) => write!(f, "Not found"),
|
||||
ErrorKind::Std(std::io::ErrorKind::NotFound, _) => write!(f, "Not found"),
|
||||
ErrorKind::FileNotFound => write!(f, "File not found"),
|
||||
ErrorKind::DirectoryNotFound => write!(f, "Directory not found"),
|
||||
_ => write!(f, "I/O error"),
|
||||
@ -323,13 +394,14 @@ impl Display for IoError {
|
||||
impl Display for ErrorKind {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ErrorKind::Std(std::io::ErrorKind::NotFound) => write!(f, "Not found"),
|
||||
ErrorKind::Std(error_kind) => {
|
||||
ErrorKind::Std(std::io::ErrorKind::NotFound, _) => write!(f, "Not found"),
|
||||
ErrorKind::Std(error_kind, _) => {
|
||||
let msg = error_kind.to_string();
|
||||
let (first, rest) = msg.split_at(1);
|
||||
write!(f, "{}{}", first.to_uppercase(), rest)
|
||||
}
|
||||
ErrorKind::NotAFile => write!(f, "Not a file"),
|
||||
ErrorKind::AlreadyInUse => write!(f, "Already in use"),
|
||||
ErrorKind::FileNotFound => write!(f, "File not found"),
|
||||
ErrorKind::DirectoryNotFound => write!(f, "Directory not found"),
|
||||
}
|
||||
@ -342,7 +414,7 @@ impl Diagnostic for IoError {
|
||||
fn code<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {
|
||||
let mut code = String::from("nu::shell::io::");
|
||||
match self.kind {
|
||||
ErrorKind::Std(error_kind) => match error_kind {
|
||||
ErrorKind::Std(error_kind, _) => match error_kind {
|
||||
std::io::ErrorKind::NotFound => code.push_str("not_found"),
|
||||
std::io::ErrorKind::PermissionDenied => code.push_str("permission_denied"),
|
||||
std::io::ErrorKind::ConnectionRefused => code.push_str("connection_refused"),
|
||||
@ -366,6 +438,7 @@ impl Diagnostic for IoError {
|
||||
kind => code.push_str(&kind.to_string().to_lowercase().replace(" ", "_")),
|
||||
},
|
||||
ErrorKind::NotAFile => code.push_str("not_a_file"),
|
||||
ErrorKind::AlreadyInUse => code.push_str("already_in_use"),
|
||||
ErrorKind::FileNotFound => code.push_str("file_not_found"),
|
||||
ErrorKind::DirectoryNotFound => code.push_str("directory_not_found"),
|
||||
}
|
||||
@ -378,7 +451,10 @@ impl Diagnostic for IoError {
|
||||
let path = format!("'{}'", path.display());
|
||||
match self.kind {
|
||||
ErrorKind::NotAFile => format!("{path} is not a file"),
|
||||
ErrorKind::Std(std::io::ErrorKind::NotFound)
|
||||
ErrorKind::AlreadyInUse => {
|
||||
format!("{path} is already being used by another program")
|
||||
}
|
||||
ErrorKind::Std(std::io::ErrorKind::NotFound, _)
|
||||
| ErrorKind::FileNotFound
|
||||
| ErrorKind::DirectoryNotFound => format!("{path} does not exist"),
|
||||
_ => format!("The error occurred at {path}"),
|
||||
@ -430,16 +506,10 @@ impl From<IoError> for std::io::Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::ErrorKind> for ErrorKind {
|
||||
fn from(value: std::io::ErrorKind) -> Self {
|
||||
ErrorKind::Std(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorKind> for std::io::ErrorKind {
|
||||
fn from(value: ErrorKind) -> Self {
|
||||
match value {
|
||||
ErrorKind::Std(error_kind) => error_kind,
|
||||
ErrorKind::Std(error_kind, _) => error_kind,
|
||||
_ => std::io::ErrorKind::Other,
|
||||
}
|
||||
}
|
||||
@ -455,8 +525,8 @@ pub enum NotFound {
|
||||
Directory,
|
||||
}
|
||||
|
||||
/// Extension trait for working with [`std::io::ErrorKind`].
|
||||
pub trait ErrorKindExt {
|
||||
/// Extension trait for working with [`std::io::Error`].
|
||||
pub trait IoErrorExt {
|
||||
/// Map [`NotFound`](std::io::ErrorKind) variants into more precise variants.
|
||||
///
|
||||
/// The OS doesn't know when an entity was not found whether it was meant to be a file or a
|
||||
@ -469,7 +539,7 @@ pub trait ErrorKindExt {
|
||||
/// If the file isn't found, return [`FileNotFound`](ErrorKind::FileNotFound).
|
||||
/// ```rust
|
||||
/// # use nu_protocol::{
|
||||
/// # shell_error::io::{ErrorKind, ErrorKindExt, IoError, NotFound},
|
||||
/// # shell_error::io::{ErrorKind, IoErrorExt, IoError, NotFound},
|
||||
/// # ShellError, Span,
|
||||
/// # };
|
||||
/// # use std::{fs, path::PathBuf};
|
||||
@ -479,7 +549,7 @@ pub trait ErrorKindExt {
|
||||
/// let a_file = PathBuf::from("scripts/ellie.nu");
|
||||
/// let ellie = fs::read_to_string(&a_file).map_err(|err| {
|
||||
/// ShellError::Io(IoError::new(
|
||||
/// err.kind().not_found_as(NotFound::File),
|
||||
/// err.not_found_as(NotFound::File),
|
||||
/// span,
|
||||
/// a_file,
|
||||
/// ))
|
||||
@ -498,21 +568,46 @@ pub trait ErrorKindExt {
|
||||
fn not_found_as(self, kind: NotFound) -> ErrorKind;
|
||||
}
|
||||
|
||||
impl ErrorKindExt for std::io::ErrorKind {
|
||||
impl IoErrorExt for ErrorKind {
|
||||
fn not_found_as(self, kind: NotFound) -> ErrorKind {
|
||||
match (kind, self) {
|
||||
(NotFound::File, Self::NotFound) => ErrorKind::FileNotFound,
|
||||
(NotFound::Directory, Self::NotFound) => ErrorKind::DirectoryNotFound,
|
||||
_ => ErrorKind::Std(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrorKindExt for ErrorKind {
|
||||
fn not_found_as(self, kind: NotFound) -> ErrorKind {
|
||||
match self {
|
||||
Self::Std(std_kind) => std_kind.not_found_as(kind),
|
||||
(NotFound::File, Self::Std(std::io::ErrorKind::NotFound, _)) => ErrorKind::FileNotFound,
|
||||
(NotFound::Directory, Self::Std(std::io::ErrorKind::NotFound, _)) => {
|
||||
ErrorKind::DirectoryNotFound
|
||||
}
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IoErrorExt for std::io::Error {
|
||||
fn not_found_as(self, kind: NotFound) -> ErrorKind {
|
||||
ErrorKind::from(self).not_found_as(kind)
|
||||
}
|
||||
}
|
||||
|
||||
impl IoErrorExt for &std::io::Error {
|
||||
fn not_found_as(self, kind: NotFound) -> ErrorKind {
|
||||
ErrorKind::from(self).not_found_as(kind)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod assert_not_impl {
|
||||
use super::*;
|
||||
|
||||
/// Assertion that `ErrorKind` does not implement `From<std::io::ErrorKind>`.
|
||||
///
|
||||
/// This implementation exists only in tests to make sure that no crate,
|
||||
/// including ours, accidentally adds a `From<std::io::ErrorKind>` impl for `ErrorKind`.
|
||||
/// If someone tries, it will fail due to conflicting implementations.
|
||||
///
|
||||
/// We want to force usage of [`IoError::new`] with a full [`std::io::Error`] instead of
|
||||
/// allowing conversion from just an [`std::io::ErrorKind`].
|
||||
/// That way, we can properly inspect and classify uncategorized I/O errors.
|
||||
impl From<std::io::ErrorKind> for ErrorKind {
|
||||
fn from(_: std::io::ErrorKind) -> Self {
|
||||
unimplemented!("ErrorKind should not implement From<std::io::ErrorKind>")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ impl ByteStream {
|
||||
if let Some(mut reader) = self.reader() {
|
||||
// Copy the number of skipped bytes into the sink before proceeding
|
||||
io::copy(&mut (&mut reader).take(n), &mut io::sink())
|
||||
.map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
.map_err(|err| IoError::new(err, span, None))?;
|
||||
Ok(
|
||||
ByteStream::read(reader, span, Signals::empty(), ByteStreamType::Binary)
|
||||
.with_known_size(known_size),
|
||||
@ -367,7 +367,7 @@ impl ByteStream {
|
||||
/// binary.
|
||||
#[cfg(feature = "os")]
|
||||
pub fn stdin(span: Span) -> Result<Self, ShellError> {
|
||||
let stdin = os_pipe::dup_stdin().map_err(|err| IoError::new(err.kind(), span, None))?;
|
||||
let stdin = os_pipe::dup_stdin().map_err(|err| IoError::new(err, span, None))?;
|
||||
let source = ByteStreamSource::File(convert_file(stdin));
|
||||
Ok(Self::new(
|
||||
source,
|
||||
@ -853,7 +853,7 @@ impl Iterator for Lines {
|
||||
trim_end_newline(&mut string);
|
||||
Some(Ok(string))
|
||||
}
|
||||
Err(e) => Some(Err(IoError::new(e.kind(), self.span, None).into())),
|
||||
Err(err) => Some(Err(IoError::new(err, self.span, None).into())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1052,7 +1052,7 @@ impl Iterator for SplitRead {
|
||||
self.internal.next().map(|r| {
|
||||
r.map_err(|err| {
|
||||
ShellError::Io(IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not get next value for SplitRead",
|
||||
crate::location!(),
|
||||
))
|
||||
@ -1094,7 +1094,7 @@ impl Chunks {
|
||||
fn next_string(&mut self) -> Result<Option<String>, (Vec<u8>, ShellError)> {
|
||||
let from_io_error = |err: std::io::Error| match ShellErrorBridge::try_from(err) {
|
||||
Ok(err) => err.0,
|
||||
Err(err) => IoError::new(err.kind(), self.span, None).into(),
|
||||
Err(err) => IoError::new(err, self.span, None).into(),
|
||||
};
|
||||
|
||||
// Get some data from the reader
|
||||
@ -1177,11 +1177,7 @@ impl Iterator for Chunks {
|
||||
Ok(buf) => buf,
|
||||
Err(err) => {
|
||||
self.error = true;
|
||||
return Some(Err(ShellError::Io(IoError::new(
|
||||
err.kind(),
|
||||
self.span,
|
||||
None,
|
||||
))));
|
||||
return Some(Err(ShellError::Io(IoError::new(err, self.span, None))));
|
||||
}
|
||||
};
|
||||
if !buf.is_empty() {
|
||||
|
@ -222,14 +222,14 @@ impl PipelineData {
|
||||
let bytes = value_to_bytes(value)?;
|
||||
dest.write_all(&bytes).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not write PipelineData to dest",
|
||||
crate::location!(),
|
||||
)
|
||||
})?;
|
||||
dest.flush().map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not flush PipelineData to dest",
|
||||
crate::location!(),
|
||||
)
|
||||
@ -241,14 +241,14 @@ impl PipelineData {
|
||||
let bytes = value_to_bytes(value)?;
|
||||
dest.write_all(&bytes).map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not write PipelineData to dest",
|
||||
crate::location!(),
|
||||
)
|
||||
})?;
|
||||
dest.write_all(b"\n").map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not write linebreak after PipelineData to dest",
|
||||
crate::location!(),
|
||||
)
|
||||
@ -256,7 +256,7 @@ impl PipelineData {
|
||||
}
|
||||
dest.flush().map_err(|err| {
|
||||
IoError::new_internal(
|
||||
err.kind(),
|
||||
err,
|
||||
"Could not flush PipelineData to dest",
|
||||
crate::location!(),
|
||||
)
|
||||
@ -775,11 +775,9 @@ where
|
||||
let io_error_map = |err: std::io::Error, location: Location| {
|
||||
let context = format!("Writing to {} failed", destination_name);
|
||||
match span {
|
||||
None => IoError::new_internal(err.kind(), context, location),
|
||||
Some(span) if span == Span::unknown() => {
|
||||
IoError::new_internal(err.kind(), context, location)
|
||||
}
|
||||
Some(span) => IoError::new_with_additional_context(err.kind(), span, None, context),
|
||||
None => IoError::new_internal(err, context, location),
|
||||
Some(span) if span == Span::unknown() => IoError::new_internal(err, context, location),
|
||||
Some(span) => IoError::new_with_additional_context(err, span, None, context),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -81,7 +81,7 @@ impl ExitStatusFuture {
|
||||
}
|
||||
Ok(Ok(status)) => Ok(status),
|
||||
Ok(Err(err)) => Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
err,
|
||||
span,
|
||||
None,
|
||||
"failed to get exit code",
|
||||
@ -276,7 +276,7 @@ impl ChildProcess {
|
||||
})
|
||||
.map_err(|err| {
|
||||
IoError::new_with_additional_context(
|
||||
err.kind(),
|
||||
err,
|
||||
span,
|
||||
None,
|
||||
"Could now spawn exit status waiter",
|
||||
@ -325,7 +325,7 @@ impl ChildProcess {
|
||||
}
|
||||
|
||||
let bytes = if let Some(stdout) = self.stdout {
|
||||
collect_bytes(stdout).map_err(|err| IoError::new(err.kind(), self.span, None))?
|
||||
collect_bytes(stdout).map_err(|err| IoError::new(err, self.span, None))?
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
@ -10,7 +10,8 @@ use nu_utils::perf;
|
||||
use nu_plugin::{EvaluatedCall, PluginCommand};
|
||||
use nu_protocol::{
|
||||
Category, Example, LabeledError, PipelineData, ShellError, Signature, Span, Spanned,
|
||||
SyntaxShape, Type, Value, shell_error::io::IoError,
|
||||
SyntaxShape, Type, Value,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
|
||||
use std::{fs::File, io::BufReader, num::NonZeroUsize, path::PathBuf, sync::Arc};
|
||||
@ -193,7 +194,7 @@ fn command(
|
||||
)),
|
||||
},
|
||||
None => Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
|
||||
spanned_file.span,
|
||||
PathBuf::from(spanned_file.item),
|
||||
"File without extension",
|
||||
|
@ -16,7 +16,8 @@ use log::debug;
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||
use nu_protocol::{
|
||||
Category, Example, LabeledError, PipelineData, ShellError, Signature, Span, Spanned,
|
||||
SyntaxShape, Type, shell_error::io::IoError,
|
||||
SyntaxShape, Type,
|
||||
shell_error::{self, io::IoError},
|
||||
};
|
||||
use polars::error::PolarsError;
|
||||
|
||||
@ -212,7 +213,7 @@ fn command(
|
||||
)),
|
||||
},
|
||||
None => Err(ShellError::Io(IoError::new_with_additional_context(
|
||||
std::io::ErrorKind::NotFound,
|
||||
shell_error::io::ErrorKind::FileNotFound,
|
||||
resource.span,
|
||||
Some(PathBuf::from(resource.path)),
|
||||
"File without extension",
|
||||
|
@ -5,7 +5,7 @@ use nu_protocol::{
|
||||
DeclId, ShellError, Span, Value, VarId,
|
||||
engine::{EngineState, Stack, StateWorkingSet},
|
||||
report_shell_error,
|
||||
shell_error::io::{ErrorKindExt, IoError, NotFound},
|
||||
shell_error::io::{IoError, IoErrorExt, NotFound},
|
||||
};
|
||||
use reedline::Completer;
|
||||
use serde_json::{Value as JsonValue, json};
|
||||
@ -58,7 +58,7 @@ fn read_in_file<'a>(
|
||||
let file = std::fs::read(file_path)
|
||||
.map_err(|err| {
|
||||
ShellError::Io(IoError::new_with_additional_context(
|
||||
err.kind().not_found_as(NotFound::File),
|
||||
err.not_found_as(NotFound::File),
|
||||
Span::unknown(),
|
||||
PathBuf::from(file_path),
|
||||
"Could not read file",
|
||||
|
@ -417,7 +417,7 @@ fn main() -> Result<()> {
|
||||
let filename = canonicalize_with(&plugin_filename.item, &init_cwd)
|
||||
.map_err(|err| {
|
||||
nu_protocol::shell_error::io::IoError::new(
|
||||
err.kind(),
|
||||
err,
|
||||
plugin_filename.span,
|
||||
PathBuf::from(&plugin_filename.item),
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user