2023-05-03 11:06:20 +02:00
== Why is this an issue?
2023-06-02 17:04:44 +02:00
If an `InterruptedException` or a `ThreadDeath` error is not handled properly, the information that the thread was interrupted will be lost.
Handling this exception means either to re-throw it, or manually re-interrupt the current thread by calling `Thread.interrupt()`.
Simply logging the exception is not sufficient and counts as ignoring it.
Between the moment the exception is caught and handled, is the right time to perform cleanup operations on the method's state, if needed.
2021-04-28 16:49:39 +02:00
2023-06-02 17:04:44 +02:00
=== What is the potential impact?
2021-04-28 16:49:39 +02:00
2023-06-06 15:53:52 +02:00
Failing to interrupt the thread (or to re-throw) risks delaying the thread shutdown and loses the information that the thread was interrupted - probably without finishing its task.
2021-04-28 16:49:39 +02:00
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
=== Noncompliant code example
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,java]
2021-04-28 16:49:39 +02:00
----
public void run () {
try {
2023-06-06 15:53:52 +02:00
/*...*/
2023-06-02 17:04:44 +02:00
} catch (InterruptedException e) { // Noncompliant; logging is not enough
2021-04-28 16:49:39 +02:00
LOGGER.log(Level.WARN, "Interrupted!", e);
}
}
----
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
=== Compliant solution
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,java]
2021-04-28 16:49:39 +02:00
----
public void run () {
try {
2023-06-06 15:53:52 +02:00
/* ... */
2023-06-02 17:04:44 +02:00
} catch (InterruptedException e) { // Compliant; the interrupted state is restored
2021-04-28 16:49:39 +02:00
LOGGER.log(Level.WARN, "Interrupted!", e);
2023-06-06 15:53:52 +02:00
/* Clean up whatever needs to be handled before interrupting */
2021-04-28 16:49:39 +02:00
Thread.currentThread().interrupt();
}
}
2023-06-02 17:04:44 +02:00
public void run () {
try {
2023-06-06 15:53:52 +02:00
/* ... */
2023-06-02 17:04:44 +02:00
} catch (ThreadDeath e) { // Compliant; the error is being re-thrown
LOGGER.log(Level.WARN, "Interrupted!", e);
2023-06-06 15:53:52 +02:00
/* Clean up whatever needs to be handled before re-throwing */
2023-06-02 17:04:44 +02:00
throw e;
}
}
2021-04-28 16:49:39 +02:00
----
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
== Resources
2021-04-28 16:49:39 +02:00
2022-04-07 08:53:59 -05:00
* https://cwe.mitre.org/data/definitions/391[MITRE, CWE-391] - Unchecked Error Condition
2021-04-28 18:08:03 +02:00
2021-06-02 20:44:38 +02:00
2021-06-03 09:05:38 +02:00
ifdef::env-github,rspecator-view[]
2021-09-20 15:38:42 +02:00
'''
== Implementation Specification
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== Message
Either re-interrupt this method or rethrow the "{InterruptedException/ThreadDeath}" that can be caught here.
=== Highlighting
* Primary: Catch parameter
* Secondary: Method call throwing "InterruptedException"
2021-09-20 15:38:42 +02:00
2021-06-08 15:52:13 +02:00
'''
2021-06-02 20:44:38 +02:00
== Comments And Links
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== is related to: S5754
=== on 14 Oct 2014, 21:21:47 Freddy Mallet wrote:
2023-06-02 17:04:44 +02:00
@Ann, could you provide the source of this RSPEC because would like to double-check the main goal of this rule ? For sure here the code snippets are really misleading because we could have the feeling that when the execution of a Runnable class is interrupted, this exception can be caught in the `run` method which is not at all the case.
2023-05-25 14:18:12 +02:00
=== on 15 Oct 2014, 11:59:38 Ann Campbell wrote:
\[~freddy.mallet] \https://twitter.com/aparnachaudhary/status/520952677631807488
=== on 4 Sep 2019, 20:33:20 Réda Housni Alaoui wrote:
Hi,
I think the rule derived from this spec is too narrow.
2023-06-02 17:04:44 +02:00
Many people write `catch (Exception e)` in their applications.
2023-05-25 14:18:12 +02:00
2023-06-02 17:04:44 +02:00
Following this spec, IMO, that means that any `catch(Exception e)` must ALWAYS be preceded by a catch of InterruptedException like this
2023-05-25 14:18:12 +02:00
----
catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e) {
//...
}{code}
----
2021-06-03 09:05:38 +02:00
endif::env-github,rspecator-view[]