Slide 1

Slide 1 text

OISHI Masakuni Don’t use runCatching LY Corporation

Slide 2

Slide 2 text

What is the problem with this code?

Slide 3

Slide 3 text

runCatching catches ALL Throwables =

Slide 4

Slide 4 text

Exceptions Hierarchy in Kotlin Throwable Exception Error RuntimeException IOException NullPointerException CancellationException

Slide 5

Slide 5 text

Throwable Exception Error RuntimeException IOException NullPointerException CancellationException This is System Error. Don’t catch!

Slide 6

Slide 6 text

DO NOT catch Errors! • Error is considered an unrecoverable exception, and when it is thrown, apps should be terminated immediately. • Errors may be thrown from almost anywhere. (e.g. OutOfMemoryError) • If the app catches an Error and continues processing, the behavior of the app becomes unpredictable and can cause more serious problems.

Slide 7

Slide 7 text

DO NOT catch all Throwables • Of cause, the code “try { … } catch (e: Throwable) { … }” catches all Throwables, including Errors. Thus, you must not do so.

Slide 8

Slide 8 text

Do not implement own logging code for Throwable • Do not implement your own logging code when the app crashes. • Leave the crash logging to an application-wide framework such as Firebase Crashlytics.

Slide 9

Slide 9 text

Throwable Exception Error RuntimeException IOException NullPointerException CancellationException This is used for coroutine cancellation. Don’t catch! Don’t catch!

Slide 10

Slide 10 text

DO NOT catch CancellationException! • In Kotlin Coroutines, cancellation is performed by throwing a CancellationException. • Catching a CancellationException breaks the cancellation mechanism of coroutines.

Slide 11

Slide 11 text

Throwable Exception Error RuntimeException IOException NullPointerException CancellationException Usually, this is caused by bugs. Don’t catch! Don’t catch! Don’t catch!

Slide 12

Slide 12 text

Refrain from catching RuntimeException • RuntimeException is often thrown due to bugs. (e.g. NullPointerException) • It is a bad practice to ignore exceptions caused by bugs and continue processing. • When an exception is thrown due to a bug, the app should crash without catching it. This will make it easier to fi nd the bug in tests. • Ignoring exceptions caused by bugs may cause more serious problems.

Slide 13

Slide 13 text

A real problem we had in our app • There was a bug in a task that sends data to the server, throwing a NullPointerException. • The task was implemented to catch all exceptions and simply retry. • This bug resulted in in fi nite repetition of data transmission and a huge increase in the app's traf fi c. • We were not aware of this bug until the user complained.

Slide 14

Slide 14 text

Throwable Exception Error RuntimeException IOException NullPointerException CancellationException You should catch this! Don’t catch! Don’t catch! Don’t catch!

Slide 15

Slide 15 text

Catch specific types of exceptions • In general, failures related to interactions with outside of the app process are the exceptions that should be caught. For example, • IOException • Parsing error in API payload (e.g. JSONException) • Catch these exceptions in as speci fi c types as possible. • Note that in some libraries, even exceptions related to I/O operations extend RuntimeException. (e.g. retro fi t2.HttpException)

Slide 16

Slide 16 text

Summary • Do not catch Error • Of cause, do not catch ALL Throwables • Do not catch CancellationException • Refrain from catching RuntimeException • But some RuntimeException should be caught (e.g. retro fi t2.HttpException) • Catch speci fi c types of Exceptions

Slide 17

Slide 17 text

Best Practice • Catch expected exceptions with their speci fi c types.

Slide 18

Slide 18 text

Not the best code, but not too bad • Catch all Exceptions except CancellationException. • But note that this makes it harder to fi nd bugs.

Slide 19

Slide 19 text

Catch specific types of exceptions Throwable Exception Error RuntimeException IOException NullPointerException CancellationException You should catch this! Don’t catch! Don’t catch! Don’t catch!

Slide 20

Slide 20 text

Do not use runCatching!