diff options
author | Nayeem Rahman <nayeemrmn99@gmail.com> | 2022-05-09 10:44:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-09 11:44:50 +0200 |
commit | 23efc4fcab2ca3b8b47539a7fb1d904efc57eb7c (patch) | |
tree | 54dd76ef9d2071245c9ad28610f78c72937546eb /cli/lsp/testing/execution.rs | |
parent | ab728e9ccfff2d1ac6362b22b579b00120a39f67 (diff) |
feat(test): Represent uncaught errors (#14513)
This commit adds better reporting of uncaught errors
in top level scope of testing files. This change affects
both console runner as well as LSP runner.
Diffstat (limited to 'cli/lsp/testing/execution.rs')
-rw-r--r-- | cli/lsp/testing/execution.rs | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/cli/lsp/testing/execution.rs b/cli/lsp/testing/execution.rs index 4f4862054..358f9357b 100644 --- a/cli/lsp/testing/execution.rs +++ b/cli/lsp/testing/execution.rs @@ -20,6 +20,7 @@ use crate::tools::test::TestEventSender; use deno_core::anyhow::anyhow; use deno_core::error::AnyError; +use deno_core::error::JsError; use deno_core::futures::future; use deno_core::futures::stream; use deno_core::futures::StreamExt; @@ -181,7 +182,7 @@ async fn test_specifier( permissions: Permissions, specifier: ModuleSpecifier, mode: test::TestMode, - sender: TestEventSender, + sender: &TestEventSender, token: CancellationToken, options: Option<Value>, ) -> Result<(), AnyError> { @@ -337,22 +338,32 @@ impl TestRun { let specifier = specifier.clone(); let ps = ps.clone(); let permissions = permissions.clone(); - let sender = sender.clone(); + let mut sender = sender.clone(); let options = self.filters.get(&specifier).map(|f| f.as_test_options()); let token = self.token.clone(); tokio::task::spawn_blocking(move || { - let future = test_specifier( + let origin = specifier.to_string(); + let file_result = run_basic(test_specifier( ps, permissions, specifier, test::TestMode::Executable, - sender, + &sender, token, options, - ); - - run_basic(future) + )); + if let Err(error) = file_result { + if error.is::<JsError>() { + sender.send(test::TestEvent::UncaughtError( + origin, + Box::new(error.downcast::<JsError>().unwrap()), + ))?; + } else { + return Err(error); + } + } + Ok(()) }) }); @@ -404,6 +415,11 @@ impl TestRun { reporter.report_result(&description, &result, elapsed); } + test::TestEvent::UncaughtError(origin, error) => { + reporter.report_uncaught_error(&origin, &error); + summary.failed += 1; + summary.uncaught_errors.push((origin, error)); + } test::TestEvent::StepWait(description) => { reporter.report_step_wait(&description); } @@ -805,6 +821,37 @@ impl test::TestReporter for LspTestReporter { } } + fn report_uncaught_error(&mut self, origin: &str, js_error: &JsError) { + if self.current_origin == Some(origin.to_string()) { + self.current_origin = None; + } + let stack = self.stack.remove(origin).unwrap_or_default(); + let err_string = format!( + "Uncaught error from {}: {}\nThis error was not caught from a test and caused the test runner to fail on the referenced module.\nIt most likely originated from a dangling promise, event/timeout handler or top-level code.", + origin, + test::format_test_error(js_error) + ); + let messages = as_test_messages(err_string, false); + for t in stack.iter().rev() { + match t { + TestOrTestStepDescription::TestDescription(desc) => { + self.progress(lsp_custom::TestRunProgressMessage::Failed { + test: desc.into(), + messages: messages.clone(), + duration: None, + }); + } + TestOrTestStepDescription::TestStepDescription(desc) => { + self.progress(lsp_custom::TestRunProgressMessage::Failed { + test: desc.into(), + messages: messages.clone(), + duration: None, + }); + } + } + } + } + fn report_step_wait(&mut self, desc: &test::TestStepDescription) { if !self.includes_step(desc) { self.add_step(desc); |