CLOVIS
10/07/2024, 8:12 PMThrowable
!
https://ivan.canet.dev/blog/2024/10/07/flee-throwable.htmlYoussef Shoaib [MOD]
10/07/2024, 8:21 PMnonFatalOrRethrow
helps a lot in these situations. It's a shame that stdlib's runCatching
can swallow exceptions in such a way, but it makes sense for its intended usage (coroutines)David
10/07/2024, 9:03 PMStefan Oltmann
10/08/2024, 5:30 AMJoel Denke
10/08/2024, 6:03 AMTgo1014
10/08/2024, 8:18 AMIf you must catchShouldn’t this be, always rethrow it.Exception
Throwable
? `Exception`s are the kind of errors you can “recover from”, right?!hho
10/08/2024, 8:43 AMKlitos Kyriacou
10/08/2024, 8:48 AMRob Elliot
10/08/2024, 9:03 AMCLOVIS
10/08/2024, 6:55 PMCatching Throwable around the main() method can be a good practice in certain scenarios, primarily because it ensures that any unexpected exception or error is logged, giving you a chance to analyze the failure later.If your runtime is properly implemented, a throwable that bubbles up to the main method should already be logged somewhere by the JVM, so this adds no value. Even worse, it decreases the chances of getting useful information, because attempting to extract that information from within the process can strain it further when it is already dying. I've seen multiple times situations in which removing the global
try…catch
has increased the amount of available information available from within Kubernetes logs etc, or at the very least made it less noisy.
For instance, take UnsatisfiedLinkError. If a DLL fails to load, the default behavior would be for the program to crash. Instead of letting that happen, I prefer to catch this error and show a meaningful message to the user.But you wouldn't implement this by having a
catch (e: Throwable)
at the root of the call stack, right? That's probably not where the DLL is loaded, so you probably have some kind of method somewhere that is responsible from attempting to load the DLL and switching to an alternate implementation if it isn't available. In that method, you know that the only error you can handle is UnsatisfiedLinkError
, so you would specifically catch (e: UnsatisfiedLinkError)
. I do think this is good practice. My blog post is specifically about catching Throwable
directly, but I think catching a specific subtype of Throwable
is good practice. If you have any idea of how I could make this clearer in the post, please don't hesitate to share.
There are also ways to handle an OutOfMemoryError gracefully. If the try block is carefully structured to manage memory resources, it’s possible to recover and allow the program to continue functioning in a degraded state.Yes. But again, that part of the code will never be written as
catch (e: Throwable)
. It will be written as catch (e: OutOfMemoryError)
, because it is able to handle specifically that. By being specific, it avoids all pitfalls I mentioned of dealing with Throwable
: there is no risk of interrupting the JVM's ThreadDeath
process, etc. I have a few examples of this myself where I have a high-level catch (e: OutOfMemoryError)
that aggressively clears caches before retrying the operation.CLOVIS
10/08/2024, 6:58 PMShouldn’t this beIt would be nice if that was the case… But no, sadly, it's not possible to have a general handler even for? `Exception`s are the kind of errors you can “recover from”, right?!Throwable
Exception
because there are exceptions you shouldn't catch. Most notably in this Slack, we would know about CoroutineCancellationException
, which is a subtype of IllegalStateException
. If you catch (e: Exception)
or even catch (e: IllegalStateException)
without rethrowing them, you are creating zombie coroutines. For this specific case, I recommend @Sam's blog: https://betterprogramming.pub/the-silent-killer-thats-crashing-your-coroutines-9171d1e8f79bCLOVIS
10/08/2024, 7:00 PMCLOVIS
10/08/2024, 7:10 PMLog and rethrow generally results in noisy duplicate stacktraces, I hate it.Note that this isn't because of rethrowing. It's because it's logging an exception when there is already a handler higher in the callstack that will already log it. I didn't consider this use-case in this article because it is clearly pointless and I haven't encountered it in the real world. I'll add a section to the article.
CLOVIS
10/08/2024, 7:24 PMCLOVIS
10/08/2024, 7:48 PMCLOVIS
12/20/2024, 10:25 AMhho
12/20/2024, 2:16 PMhho
12/21/2024, 7:47 PMCLOVIS
12/30/2024, 9:04 PM