Skip to content

Commit 23efb89

Browse files
Make tests resilient to exceptions thrown while reporting exceptions (#19566)
Part of #19542. We protect against the case where `Exception.getMessage` or `Exception.getStackTrace` throw an exception. This change makes `testCompilation tests/neg/i8984.scala` fail as expected. `tests/neg/i8984.scala` is currently disabled (see #19561). `tests/neg/i8984.scala` will not be fixed in this PR. Making the test framework more resilient is a priority. Fixing this is the last part of #19542.
2 parents fbe06c0 + b427ba6 commit 23efb89

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

Diff for: compiler/test/dotty/tools/vulpix/ParallelTesting.scala

+18-8
Original file line numberDiff line numberDiff line change
@@ -290,15 +290,25 @@ trait ParallelTesting extends RunnerOrchestration { self =>
290290

291291
/** This callback is executed once the compilation of this test source finished */
292292
private final def onComplete(testSource: TestSource, reportersOrCrash: Try[Seq[TestReporter]], logger: LoggedRunnable): Unit =
293-
reportersOrCrash match {
294-
case TryFailure(exn) => onFailure(testSource, Nil, logger, Some(s"Fatal compiler crash when compiling: ${testSource.title}:\n${exn.getMessage}${exn.getStackTrace.map("\n\tat " + _).mkString}"))
295-
case TrySuccess(reporters) if !reporters.exists(_.skipped) =>
296-
maybeFailureMessage(testSource, reporters) match {
297-
case Some(msg) => onFailure(testSource, reporters, logger, Option(msg).filter(_.nonEmpty))
298-
case None => onSuccess(testSource, reporters, logger)
293+
try
294+
reportersOrCrash match
295+
case TryFailure(exn) => onFailure(testSource, Nil, logger, Some(s"Fatal compiler crash when compiling: ${testSource.title}:\n${exn.getMessage}${exn.getStackTrace.map("\n\tat " + _).mkString}"))
296+
case TrySuccess(reporters) if !reporters.exists(_.skipped) =>
297+
maybeFailureMessage(testSource, reporters) match {
298+
case Some(msg) => onFailure(testSource, reporters, logger, Option(msg).filter(_.nonEmpty))
299+
case None => onSuccess(testSource, reporters, logger)
300+
}
301+
case _ =>
302+
catch case ex: Throwable =>
303+
echo(s"Exception thrown onComplete (probably by a reporter) in $testSource: ${ex.getClass}")
304+
Try(ex.printStackTrace())
305+
.recover{ _ =>
306+
val trace = ex.getStackTrace.map(_.toString) // compute this first in case getStackTrace throws an exception
307+
echo(s"${ex.getClass.getName} message could not be printed due to an exception while computing the message.")
308+
if trace.nonEmpty then trace.foreach(echo) else echo(s"${ex.getClass.getName} stack trace is empty.")
299309
}
300-
case _ =>
301-
}
310+
.getOrElse(echo(s"${ex.getClass.getName} stack trace could not be printed due to an exception while printing the stack trace."))
311+
failTestSource(testSource)
302312

303313
/**
304314
* Based on the reporters obtained after the compilation, determines if this test has failed.

0 commit comments

Comments
 (0)