Skip to content

Stop catching Throwable/IIOBE/NPE in the compiler, outside of stack overflow handling#25832

Merged
SolalPirelli merged 11 commits into
scala:mainfrom
dotty-staging:solal/no-catch-throwable
Apr 29, 2026
Merged

Stop catching Throwable/IIOBE/NPE in the compiler, outside of stack overflow handling#25832
SolalPirelli merged 11 commits into
scala:mainfrom
dotty-staging:solal/no-catch-throwable

Conversation

@SolalPirelli
Copy link
Copy Markdown
Contributor

@SolalPirelli SolalPirelli commented Apr 16, 2026

Part of #25799

How much have you relied on LLM-based tools in this contribution?

Not at all

How was the solution tested?

Covered by existing tests (this is a refactoring)

@SolalPirelli SolalPirelli requested a review from a team as a code owner April 16, 2026 15:39
@SolalPirelli SolalPirelli added the needs-squashing PR whose commits should be squashed by the author or via the "Squash and Merge" button label Apr 16, 2026
@SolalPirelli SolalPirelli requested a review from mbovel April 17, 2026 09:48
case ex: ClosedByInterruptException =>
try Files.deleteIfExists(path) // don't leave a empty of half-written classfile around after an interrupt
catch { case _: Throwable => () }
catch { case _: java.io.IOException => () }
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the IO-related ones I followed the Javadoc, and in one case removed a catch because it was calling one of our own util methods that already catches and ignores internally

case ex: CompilationUnit.SuspendException => throw ex
case ex: Throwable =>
if !ex.isInstanceOf[TypeError] then ex.printStackTrace()
case ex: TypeError =>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that we were willing to print a stack trace for non-typeerrors, I think letting it bubble up to "compiler bug" is better

Copy link
Copy Markdown
Contributor Author

@SolalPirelli SolalPirelli Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: double check that if something bad happens in the backend we get the usual compiler "plz file a bug" message (says Seb)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, we do

catch {
case ex: Throwable =>
handleRecursive("member names", i"of $this", ex)
case ex: Throwable => handleRecursive("member names", i"of $this", ex)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the formatting for the handleRecursives where it was easy to do so they're easier to look at in search results, since I'll deal with those in the next step

Copy link
Copy Markdown
Member

@lrytz lrytz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the standard library this looks like a very substantial breaking change that I think we cannot "just" do?

Comment thread library/src/scala/concurrent/impl/Promise.scala Outdated
@SolalPirelli SolalPirelli force-pushed the solal/no-catch-throwable branch from e40c10d to a9d11dc Compare April 21, 2026 13:26
@SolalPirelli SolalPirelli requested a review from sjrd April 24, 2026 13:03
@SolalPirelli SolalPirelli force-pushed the solal/no-catch-throwable branch 3 times, most recently from 3381d22 to 11742a6 Compare April 24, 2026 13:34
Copy link
Copy Markdown
Member

@mbovel mbovel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed orally, I was wondering if NonFatal is really the right tool (it seems ad hoc, will need to be updated, is potentially slow with its 5 type tests, etc.) or if we could more radically only catch Exception instead of Throwable. I believe it was the original idea behind the separation between Error and Exception, but I don't know if it would be practical.

@SolalPirelli SolalPirelli force-pushed the solal/no-catch-throwable branch 2 times, most recently from 2c3a9b3 to 3a196e0 Compare April 28, 2026 13:10
Interpreter.suspendOnMissing(sym, origin, annot.tree)
// We're dealing with user-thrown things here, so we must use NonFatal to catch anything realistic,
// including `Error`s like `NotImplementedError`
case NonFatal(ex) =>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only remaining use of NonFatal, can't really get rid of it :/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fun fact: ??? is an Error not an Exception so if someone uses it in a macro we have to be able to catch that... there is indeed a test that does so

@SolalPirelli SolalPirelli changed the title Stop catching Throwable, outside of stack overflow handling Stop catching Throwable outside of stack overflow handling + IOOBE + NPE Apr 28, 2026
@SolalPirelli SolalPirelli requested a review from mbovel April 29, 2026 08:32
val instantiated = dealiased.instantiate(args)
if (followAlias) instantiated.normalized else instantiated
catch
case ex: Throwable => handleRecursive("try to instantiate", i"$dealiased[$args%, %]", ex)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only non-mechanical change, I had to add a specific guard for what the catch case IndexOutOfBoundsException was trying to prevent

Copy link
Copy Markdown
Member

@sjrd sjrd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the title still accurate? It suggests that we still catch IOOBE and NPE, but the PR content suggests that those are not caught anymore.

Comment thread compiler/src/dotty/tools/dotc/reporting/messages.scala Outdated
case e: Exception =>
println(s"Compile $path exception:")
e.printStackTrace()
throw e
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intended?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should drop exceptions on the floor during tests. I've already had to fix one such case in another PR where I was seeing crashes due to stack overflows while running tests yet the tests "passed"

Comment thread compiler/test/dotty/tools/vulpix/ParallelTesting.scala Outdated
Comment thread compiler/test/dotty/tools/vulpix/ParallelTesting.scala Outdated
Comment thread compiler/test/dotty/tools/vulpix/RunnerOrchestration.scala Outdated
Comment thread compiler/test/dotty/tools/utils.scala Outdated
Comment thread docs/_docs/reference/error-codes/E001.md Outdated
Comment thread library/src/scala/concurrent/impl/FutureConvertersImpl.scala Outdated
@SolalPirelli SolalPirelli changed the title Stop catching Throwable outside of stack overflow handling + IOOBE + NPE Stop catching Throwable/IIOBE/NPE in the compiler, outside of stack overflow handling Apr 29, 2026
@SolalPirelli SolalPirelli force-pushed the solal/no-catch-throwable branch from 72ad800 to fb22933 Compare April 29, 2026 09:10
@SolalPirelli SolalPirelli requested a review from sjrd April 29, 2026 09:11
@SolalPirelli SolalPirelli merged commit a06284b into scala:main Apr 29, 2026
53 of 54 checks passed
@SolalPirelli SolalPirelli deleted the solal/no-catch-throwable branch April 29, 2026 11:10
mbovel pushed a commit to mbovel/dotty that referenced this pull request May 4, 2026
…verflow handling (scala#25832)

Part of scala#25799

## How much have you relied on LLM-based tools in this contribution?

Not at all

## How was the solution tested?

Covered by existing tests (this is a refactoring)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-squashing PR whose commits should be squashed by the author or via the "Squash and Merge" button

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants