Permalink
Browse files

DRYer crash reports.

 - Add the supplementary message only once per run, so we don't
   output the same information as we bubble up through a sequence
   of well-intentioned exception handlers.
 - In Driver, don't report message of a `FatalException`
   immediately after reporting the message and stack trace.
    - Rename `logThrowable` to `reportThrowable`, which is what it
      actually does.

The difference in output is visible:

  https://gist.github.com/4242138
  • Loading branch information...
1 parent 0acb8a3 commit 69f4e93af00a7bcc0f859460d3a1d4a47605a5dd @retronym retronym committed Dec 8, 2012
Showing with 44 additions and 35 deletions.
  1. +3 −3 src/compiler/scala/tools/nsc/Driver.scala
  2. +41 −32 src/compiler/scala/tools/nsc/Global.scala
View
6 src/compiler/scala/tools/nsc/Driver.scala
@@ -54,10 +54,10 @@ abstract class Driver {
doCompile(compiler)
} catch {
case ex: Throwable =>
- compiler.logThrowable(ex)
+ compiler.reportThrowable(ex)
ex match {
- case FatalError(msg) => reporter.error(null, "fatal error: " + msg)
- case _ => throw ex
+ case FatalError(msg) => // signals that we should fail compilation.
+ case _ => throw ex // unexpected error, tell the outside world.
}
}
}
View
73 src/compiler/scala/tools/nsc/Global.scala
@@ -292,7 +292,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
log(msg)
}
- def logThrowable(t: Throwable): Unit = globalError(throwableAsString(t))
+ @deprecated("Renamed to reportThrowable", "2.10.1")
+ def logThrowable(t: Throwable): Unit = reportThrowable(t)
+ def reportThrowable(t: Throwable): Unit = globalError(throwableAsString(t))
override def throwableAsString(t: Throwable) = util.stackTraceString(t)
// ------------ File interface -----------------------------------------
@@ -1144,37 +1146,41 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Don't want to introduce new errors trying to report errors,
* so swallow exceptions.
*/
- override def supplementErrorMessage(errorMessage: String): String = try {
- val tree = analyzer.lastTreeToTyper
- val sym = tree.symbol
- val tpe = tree.tpe
- val enclosing = lastSeenContext.enclClassOrMethod.tree
-
- val info1 = formatExplain(
- "while compiling" -> currentSource.path,
- "during phase" -> ( if (globalPhase eq phase) phase else "global=%s, atPhase=%s".format(globalPhase, phase) ),
- "library version" -> scala.util.Properties.versionString,
- "compiler version" -> Properties.versionString,
- "reconstructed args" -> settings.recreateArgs.mkString(" ")
- )
- val info2 = formatExplain(
- "last tree to typer" -> tree.summaryString,
- "symbol" -> Option(sym).fold("null")(_.debugLocationString),
- "symbol definition" -> Option(sym).fold("null")(_.defString),
- "tpe" -> tpe,
- "symbol owners" -> ownerChainString(sym),
- "context owners" -> ownerChainString(lastSeenContext.owner)
- )
- val info3: List[String] = (
- ( List("== Enclosing template or block ==", nodePrinters.nodeToString(enclosing).trim) )
- ++ ( if (tpe eq null) Nil else List("== Expanded type of tree ==", typeDeconstruct.show(tpe)) )
- ++ ( if (!opt.debug) Nil else List("== Current unit body ==", nodePrinters.nodeToString(currentUnit.body)) )
- ++ ( List(errorMessage) )
- )
-
- ("\n" + info1) :: info2 :: info3 mkString "\n\n"
- }
- catch { case x: Exception => errorMessage }
+ override def supplementErrorMessage(errorMessage: String): String =
+ if (currentRun.supplementedError) errorMessage
+ else try {
+ val tree = analyzer.lastTreeToTyper
+ val sym = tree.symbol
+ val tpe = tree.tpe
+ val enclosing = lastSeenContext.enclClassOrMethod.tree
+
+ val info1 = formatExplain(
+ "while compiling" -> currentSource.path,
+ "during phase" -> ( if (globalPhase eq phase) phase else "global=%s, atPhase=%s".format(globalPhase, phase) ),
+ "library version" -> scala.util.Properties.versionString,
+ "compiler version" -> Properties.versionString,
+ "reconstructed args" -> settings.recreateArgs.mkString(" ")
+ )
+ val info2 = formatExplain(
+ "last tree to typer" -> tree.summaryString,
+ "symbol" -> Option(sym).fold("null")(_.debugLocationString),
+ "symbol definition" -> Option(sym).fold("null")(_.defString),
+ "tpe" -> tpe,
+ "symbol owners" -> ownerChainString(sym),
+ "context owners" -> ownerChainString(lastSeenContext.owner)
+ )
+ val info3: List[String] = (
+ ( List("== Enclosing template or block ==", nodePrinters.nodeToString(enclosing).trim) )
+ ++ ( if (tpe eq null) Nil else List("== Expanded type of tree ==", typeDeconstruct.show(tpe)) )
+ ++ ( if (!opt.debug) Nil else List("== Current unit body ==", nodePrinters.nodeToString(currentUnit.body)) )
+ ++ ( List(errorMessage) )
+ )
+
+ currentRun.supplementedError = true
+
+ ("\n" + info1) :: info2 :: info3 mkString "\n\n"
+ }
+ catch { case x: Exception => errorMessage }
/** The id of the currently active run
*/
@@ -1230,6 +1236,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Has any macro expansion used a fallback during this run? */
var seenMacroExpansionsFallingBack = false
+ /** Have we already supplemented the error message of a compiler crash? */
+ private[nsc] final var supplementedError = false
+
/** To be initialized from firstPhase. */
private var terminalPhase: Phase = NoPhase

0 comments on commit 69f4e93

Please sign in to comment.