mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
fix(repl): Prevent panic on broken pipe (#21945)
This commit is contained in:
parent
1c4db2aca9
commit
0eba180fdb
2 changed files with 43 additions and 5 deletions
|
@ -1,5 +1,8 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::args::CliOptions;
|
use crate::args::CliOptions;
|
||||||
|
@ -241,15 +244,24 @@ pub async fn run(
|
||||||
|
|
||||||
// Doing this manually, instead of using `log::info!` because these messages
|
// Doing this manually, instead of using `log::info!` because these messages
|
||||||
// are supposed to go to stdout, not stderr.
|
// are supposed to go to stdout, not stderr.
|
||||||
|
// Using writeln, because println panics in certain cases
|
||||||
|
// (eg: broken pipes - https://github.com/denoland/deno/issues/21861)
|
||||||
if !cli_options.is_quiet() {
|
if !cli_options.is_quiet() {
|
||||||
println!("Deno {}", crate::version::DENO_VERSION_INFO.deno);
|
let mut handle = io::stdout().lock();
|
||||||
println!("exit using ctrl+d, ctrl+c, or close()");
|
|
||||||
|
writeln!(handle, "Deno {}", crate::version::DENO_VERSION_INFO.deno)?;
|
||||||
|
writeln!(handle, "exit using ctrl+d, ctrl+c, or close()")?;
|
||||||
|
|
||||||
if repl_flags.is_default_command {
|
if repl_flags.is_default_command {
|
||||||
println!(
|
writeln!(
|
||||||
|
handle,
|
||||||
"{}",
|
"{}",
|
||||||
colors::yellow("REPL is running with all permissions allowed.")
|
colors::yellow("REPL is running with all permissions allowed.")
|
||||||
);
|
)?;
|
||||||
println!("To specify permissions, run `deno repl` with allow flags.")
|
writeln!(
|
||||||
|
handle,
|
||||||
|
"To specify permissions, run `deno repl` with allow flags."
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4343,6 +4343,32 @@ fn broken_stdout() {
|
||||||
assert!(!stderr.contains("panic"));
|
assert!(!stderr.contains("panic"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn broken_stdout_repl() {
|
||||||
|
let (reader, writer) = os_pipe::pipe().unwrap();
|
||||||
|
// drop the reader to create a broken pipe
|
||||||
|
drop(reader);
|
||||||
|
|
||||||
|
let output = util::deno_cmd()
|
||||||
|
.current_dir(util::testdata_path())
|
||||||
|
.arg("repl")
|
||||||
|
.stdout(writer)
|
||||||
|
.stderr_piped()
|
||||||
|
.spawn()
|
||||||
|
.unwrap()
|
||||||
|
.wait_with_output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(!output.status.success());
|
||||||
|
let stderr = std::str::from_utf8(output.stderr.as_ref()).unwrap().trim();
|
||||||
|
if cfg!(windows) {
|
||||||
|
assert_contains!(stderr, "The pipe is being closed. (os error 232)");
|
||||||
|
} else {
|
||||||
|
assert_contains!(stderr, "Broken pipe (os error 32)");
|
||||||
|
}
|
||||||
|
assert_not_contains!(stderr, "panic");
|
||||||
|
}
|
||||||
|
|
||||||
itest!(error_cause {
|
itest!(error_cause {
|
||||||
args: "run run/error_cause.ts",
|
args: "run run/error_cause.ts",
|
||||||
output: "run/error_cause.ts.out",
|
output: "run/error_cause.ts.out",
|
||||||
|
|
Loading…
Reference in a new issue