-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider annotating InvocationTargetException
, ExecutionException
, and CompletionException
causes as non-nullable
#490
Comments
(A somewhat similar case is [edit: As noted in the next post, the JDK actually gets this right.] |
Hmm, I may be wrong about The code I'd remembered from before is here: My read was that that would resulting in throwing if the list of tasks were empty. But the Javadoc (even as far back as JDK 11, maybe earlier) says "throws And I see multiple guards against emptiness:
I'd have to read the code more to see if the code I was worried about can ever actually execute. I could also check whether the behavior changed over time, and I could check whether I wrote about this somewhere in the reference checker. |
InvocationTargetException
cause as non-nullableInvocationTargetException
, ExecutionException
, and CompletionException
causes as non-nullable
Here's what I had written in the reference checker: https://github.com/jspecify/jspecify-reference-checker/blob/75aa1de2a8f88f8c23347d86465844df9887874c/src/main/java/com/google/jspecify/nullness/NullSpecAnnotatedTypeFactory.java#L1126-L1148 The link there has broken, but yes, I was referring the code I thought I was: https://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/jsr166/src/main/java/util/concurrent/AbstractExecutorService.java?revision=1.54&view=markup#l185 Even at that version, I see the emptiness checks. So I think I was just wrong about the possibility of a cause-less None of that takes away from the fact that In Google's codebase, I don't see any usages of the no-arg Anyway, I'm generalizing this issue to be about both types, plus There are likely even more exception classes whose cause is never null, as noted recently in jspecify/jdk@cb92206. In those cases, we already don't use |
On the Guava front:
|
FWIW the times I have used So I think you have the right idea on nonnull at least from my experience. Also the internal constructors being passed |
Thanks. That's an interesting point about JEP 447. (If anyone has experience with really wanting to pass The other point I'd meant to add (previously expressed in this code comment) was that it could be inconvenient for code like |
…hat don't accept a cause. Callers commonly assume that instances of these types have a cause, and in practice, they nearly always do. See jspecify/jspecify#490. RELNOTES=`util.concurrent`: Deprecated the constructors of `UncheckedExecutionException` and `ExecutionError` that don't accept a cause. We won't remove these constructors, but we recommend migrating off them, as users of those classes often assume that instances will contain a cause. PiperOrigin-RevId: 613601480
…hat don't accept a cause. Callers commonly assume that instances of these types have a cause, and in practice, they nearly always do. See jspecify/jspecify#490. RELNOTES=`util.concurrent`: Deprecated the constructors of `UncheckedExecutionException` and `ExecutionError` that don't accept a cause. We won't remove these constructors, but we recommend migrating off them, as users of those classes often assume that instances will contain a cause. PiperOrigin-RevId: 613601480
…hat don't accept a cause. Callers commonly assume that instances of these types have a cause, and in practice, they nearly always do. See jspecify/jspecify#490. RELNOTES=`util.concurrent`: Deprecated the constructors of `UncheckedExecutionException` and `ExecutionError` that don't accept a cause. We won't remove these constructors, but we recommend migrating off them, as users of those classes often assume that instances will contain a cause. PiperOrigin-RevId: 613614892
So these are exception types which "should" never have a null cause, as they are specified to be thrown in reaction to some previous exception. I think the I think the same goes for As for the constructors, JEP 447 changes nothing for us (for a long time). I feel like they should also be non-null; again, user can restructure or suppress. (Recall that I view suppressions as just part of life, not evil. I just want the user to have a feeling while doing it like "okay, I can understand why it doesn't know this is safe".) Do we align? |
|
First,
InvocationTargetException
.Points in favor of non-nullable:
Throwable
constructor overload isprotected
, notpublic
—and AFAICT is unused both in the JDK and Google's codebase.InvocationTargetException
that I have ever seen has had a non-nullable cause.Points against:
getCause()
explicitly documents that the return value "may benull
" :( This may have been copied without a ton of thought fromThrowable.getCause()
, but I notice that the phrasing does not match that inThrowable.getCause()
(at least currently), so it wasn't literal copy-and-paste.No signal either way:
getTargetException
doesn't mentionnull
.The text was updated successfully, but these errors were encountered: