0

Android: Add JavaUtils.throwUnchecked()

A means of reducing binary size and excessive stack trace
"caused by" clauses.

Bug: None
Change-Id: I4705b0b1a7cd712f6c9fa9c73be8822b082b8b40
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5594290
Reviewed-by: Nate Fischer <ntfschr@chromium.org>
Commit-Queue: Andrew Grieve <agrieve@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#1311328}
This commit is contained in:
Andrew Grieve
2024-06-06 16:31:47 +00:00
committed by Chromium LUCI CQ
parent fd4b6364db
commit 1210d14523
11 changed files with 123 additions and 36 deletions

@ -39,14 +39,34 @@ try (var ignored = StrictModeContext.allowDiskWrites()) {
### Exceptions
We discourage overly broad catches via `Throwable`, `Exception`, or
`RuntimeException`, except when dealing with `RemoteException` or similar
system APIs.
A quick primer:
* `Throwable`: Base class for all exceptions
* `Error`: Base class for exceptions which are meant to crash the app.
* `Exception`: Base class for exceptions that make sense the `catch`.
* `RuntimeException`: Base class for exceptions that do not need to be
declared as `throws` ("unchecked exceptions").
#### Broad Catch Handlers {#broad-catches}
Use catch statements that do not catch exceptions they are not meant to.
* There is rarely a valid reason to `catch (Throwable t)`, since that
includes the (generally unrecoverable) `Error` types.
Use `catch (Exception e)` when working with OS APIs that might throw
(assuming the program can recover from them).
* There have been many cases of crashes caused by `IllegalStateException` /
`IllegalArgumentException` / `SecurityException` being thrown where only
`RemoteException` was being caught. In these cases, use
`catch (RemoteException | RuntimeException e)`.
* For all broad catch expressions, add a comment to explain why.
`RemoteException` was being caught. Unless catch handlers will differ
based on exception type, just catch `Exception`.
Do not use `catch (RuntimeException e)`.
* It is useful to extend `RuntimeException` to make unchecked exception
types, but the type does not make much sense in `catch` clauses, as
there are not times when you'd want to catch all unchecked exceptions,
but not also want to catch all checked exceptions.
#### Exception Messages {#exception-messages}
Avoid adding messages to exceptions that do not aid in debugging. For example:
@ -63,6 +83,31 @@ try {
}
```
#### Wrapping with RuntimeException {#throw-unchecked}
It is common to wrap a checked exception with a RuntimeException for cases
where a checked exception is not recoverable, or not possible. In order to
reduce the number of stack trace "caused by" clauses, and to save on binary
size, use [`JavaUtils.throwUnchecked()`] instead.
```java
try {
somethingThatThrowsIOException();
} catch (IOException e) {
// Bad - RuntimeException adds no context and creates longer stack traces.
throw new RuntimeException(e);
// Good - Original exception is preserved.
throw JavaUtils.throwUnchecked(e);
}
```
*** note
Do not use `throwUnchecked()` when the exception may want to be caught.
***
[`JavaUtils.throwUnchecked()`]: https://source.chromium.org/search?q=symbol:JavaUtils.throwUnchecked
### Asserts
The build system: