Skip to content

Commit

Permalink
Make tests resilient to exceptions thrown while reporting exceptions
Browse files Browse the repository at this point in the history
Part of #19542. We protect against the case where `Exception.getMessage` or
`Exception.getStackTrace` throw an exception.
  • Loading branch information
nicolasstucki committed Jan 30, 2024
1 parent 1716bcd commit b427ba6
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions compiler/test/dotty/tools/vulpix/ParallelTesting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,25 @@ trait ParallelTesting extends RunnerOrchestration { self =>

/** This callback is executed once the compilation of this test source finished */
private final def onComplete(testSource: TestSource, reportersOrCrash: Try[Seq[TestReporter]], logger: LoggedRunnable): Unit =
reportersOrCrash match {
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}"))
case TrySuccess(reporters) if !reporters.exists(_.skipped) =>
maybeFailureMessage(testSource, reporters) match {
case Some(msg) => onFailure(testSource, reporters, logger, Option(msg).filter(_.nonEmpty))
case None => onSuccess(testSource, reporters, logger)
try
reportersOrCrash match
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}"))
case TrySuccess(reporters) if !reporters.exists(_.skipped) =>
maybeFailureMessage(testSource, reporters) match {
case Some(msg) => onFailure(testSource, reporters, logger, Option(msg).filter(_.nonEmpty))
case None => onSuccess(testSource, reporters, logger)
}
case _ =>
catch case ex: Throwable =>
echo(s"Exception thrown onComplete (probably by a reporter) in $testSource: ${ex.getClass}")
Try(ex.printStackTrace())
.recover{ _ =>
val trace = ex.getStackTrace.map(_.toString) // compute this first in case getStackTrace throws an exception
echo(s"${ex.getClass.getName} message could not be printed due to an exception while computing the message.")
if trace.nonEmpty then trace.foreach(echo) else echo(s"${ex.getClass.getName} stack trace is empty.")
}
case _ =>
}
.getOrElse(echo(s"${ex.getClass.getName} stack trace could not be printed due to an exception while printing the stack trace."))
failTestSource(testSource)

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

0 comments on commit b427ba6

Please sign in to comment.