summaryrefslogtreecommitdiff
path: root/cli/lsp/testing/execution.rs
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2022-05-09 10:44:50 +0100
committerGitHub <noreply@github.com>2022-05-09 11:44:50 +0200
commit23efc4fcab2ca3b8b47539a7fb1d904efc57eb7c (patch)
tree54dd76ef9d2071245c9ad28610f78c72937546eb /cli/lsp/testing/execution.rs
parentab728e9ccfff2d1ac6362b22b579b00120a39f67 (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.rs61
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);