summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tools/repl/mod.rs22
-rw-r--r--tests/integration/run_tests.rs26
2 files changed, 43 insertions, 5 deletions
diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs
index d754b4dd2..ed3d94c84 100644
--- a/cli/tools/repl/mod.rs
+++ b/cli/tools/repl/mod.rs
@@ -1,5 +1,8 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+use std::io;
+use std::io::Write;
+
use std::sync::Arc;
use crate::args::CliOptions;
@@ -241,15 +244,24 @@ pub async fn run(
// Doing this manually, instead of using `log::info!` because these messages
// 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() {
- println!("Deno {}", crate::version::DENO_VERSION_INFO.deno);
- println!("exit using ctrl+d, ctrl+c, or close()");
+ let mut handle = io::stdout().lock();
+
+ 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 {
- println!(
+ writeln!(
+ handle,
"{}",
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."
+ )?;
}
}
diff --git a/tests/integration/run_tests.rs b/tests/integration/run_tests.rs
index 0b3d85deb..c6637e005 100644
--- a/tests/integration/run_tests.rs
+++ b/tests/integration/run_tests.rs
@@ -4343,6 +4343,32 @@ fn broken_stdout() {
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 {
args: "run run/error_cause.ts",
output: "run/error_cause.ts.out",