mirror of
https://github.com/denoland/deno.git
synced 2024-12-01 16:51:13 -05:00
fix(watch): ignore unload errors on drop (#15782)
This commit is contained in:
parent
1cf7f15c9d
commit
f0e62ced6d
3 changed files with 48 additions and 10 deletions
|
@ -1038,6 +1038,40 @@ fn test_watch_module_graph_error_referrer() {
|
||||||
check_alive_then_kill(child);
|
check_alive_then_kill(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regression test for https://github.com/denoland/deno/issues/15428.
|
||||||
|
#[test]
|
||||||
|
fn test_watch_unload_handler_error_on_drop() {
|
||||||
|
let t = TempDir::new();
|
||||||
|
let file_to_watch = t.path().join("file_to_watch.js");
|
||||||
|
write(
|
||||||
|
&file_to_watch,
|
||||||
|
r#"
|
||||||
|
addEventListener("unload", () => {
|
||||||
|
throw new Error("foo");
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
throw new Error("bar");
|
||||||
|
});
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let mut child = util::deno_cmd()
|
||||||
|
.current_dir(util::testdata_path())
|
||||||
|
.arg("run")
|
||||||
|
.arg("--watch")
|
||||||
|
.arg(&file_to_watch)
|
||||||
|
.env("NO_COLOR", "1")
|
||||||
|
.stdout(std::process::Stdio::piped())
|
||||||
|
.stderr(std::process::Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
let (_, mut stderr_lines) = child_lines(&mut child);
|
||||||
|
wait_contains("Process started", &mut stderr_lines);
|
||||||
|
wait_contains("Uncaught Error: bar", &mut stderr_lines);
|
||||||
|
wait_contains("Process finished", &mut stderr_lines);
|
||||||
|
check_alive_then_kill(child);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn run_watch_dynamic_imports() {
|
fn run_watch_dynamic_imports() {
|
||||||
let t = TempDir::new();
|
let t = TempDir::new();
|
||||||
|
|
|
@ -125,13 +125,18 @@ impl CliMainWorker {
|
||||||
self.pending_unload = true;
|
self.pending_unload = true;
|
||||||
|
|
||||||
let result = loop {
|
let result = loop {
|
||||||
let result = self.inner.worker.run_event_loop(false).await;
|
match self.inner.worker.run_event_loop(false).await {
|
||||||
if !self
|
Ok(()) => {}
|
||||||
|
Err(error) => break Err(error),
|
||||||
|
}
|
||||||
|
match self
|
||||||
.inner
|
.inner
|
||||||
.worker
|
.worker
|
||||||
.dispatch_beforeunload_event(&located_script_name!())?
|
.dispatch_beforeunload_event(&located_script_name!())
|
||||||
{
|
{
|
||||||
break result;
|
Ok(default_prevented) if default_prevented => {} // continue loop
|
||||||
|
Ok(_) => break Ok(()),
|
||||||
|
Err(error) => break Err(error),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.pending_unload = false;
|
self.pending_unload = false;
|
||||||
|
@ -152,11 +157,10 @@ impl CliMainWorker {
|
||||||
impl Drop for FileWatcherModuleExecutor {
|
impl Drop for FileWatcherModuleExecutor {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.pending_unload {
|
if self.pending_unload {
|
||||||
self
|
let _ = self
|
||||||
.inner
|
.inner
|
||||||
.worker
|
.worker
|
||||||
.dispatch_unload_event(&located_script_name!())
|
.dispatch_unload_event(&located_script_name!());
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1167,11 +1167,11 @@ pub(crate) fn exception_to_err_result<'s, T>(
|
||||||
// If termination is the result of a `op_dispatch_exception` call, we want
|
// If termination is the result of a `op_dispatch_exception` call, we want
|
||||||
// to use the exception that was passed to it rather than the exception that
|
// to use the exception that was passed to it rather than the exception that
|
||||||
// was passed to this function.
|
// was passed to this function.
|
||||||
let mut state = state_rc.borrow_mut();
|
let state = state_rc.borrow();
|
||||||
exception = state
|
exception = state
|
||||||
.dispatched_exceptions
|
.dispatched_exceptions
|
||||||
.pop_back()
|
.back()
|
||||||
.map(|exception| v8::Local::new(scope, exception))
|
.map(|exception| v8::Local::new(scope, exception.clone()))
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
// Maybe make a new exception object.
|
// Maybe make a new exception object.
|
||||||
if was_terminating_execution && exception.is_null_or_undefined() {
|
if was_terminating_execution && exception.is_null_or_undefined() {
|
||||||
|
|
Loading…
Reference in a new issue