Skip to content

Fix InterruptedException silently dropping task in SmartExecutor.Limited.submit(Runnable)#2012

Merged
cstamas merged 2 commits into
masterfrom
fix-interrupted-exception-1993
Jul 24, 2026
Merged

Fix InterruptedException silently dropping task in SmartExecutor.Limited.submit(Runnable)#2012
cstamas merged 2 commits into
masterfrom
fix-interrupted-exception-1993

Conversation

@elharo

@elharo elharo commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #1993

In Limited.submit(Runnable) (line 155), if semaphore.acquire() throws InterruptedException, the interrupt flag was restored but the caller's task was never executed — it was silently dropped. The submit(Callable) variant correctly handles this by returning a failed CompletableFuture.

This fix throws a RuntimeException wrapping the InterruptedException after restoring the interrupt flag, so the caller is notified that the task could not be submitted.

}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing a raw RuntimeException is an antipattern. Is there a subclass of RuntimeException we could throw instead?

Whatever exception we throw should be documented in javadoc for this method.

Is the exception handled upstream or is that something we also need to do?

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a correctness issue in SmartExecutor.Limited.submit(Runnable) where an InterruptedException during semaphore.acquire() would restore the interrupt flag but silently drop the task (no execution and no signal to the caller). This change makes the failure visible to callers by throwing after restoring the interrupt status.

Changes:

  • In Limited.submit(Runnable), on InterruptedException, re-interrupt the thread and throw a RuntimeException wrapping the original exception.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* @throws RejectedExecutionException If this executor cannot accept the task.
*/
void submit(Runnable runnable);
void submit(Runnable runnable) throws RejectedExecutionException;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't use throws clause for RuntimeExceptions, javadoc comment only

@cstamas
cstamas requested review from cstamas and gnodet July 24, 2026 11:29

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct fix for a real concurrency bug. The previous code silently dropped the submitted task on InterruptedException; the fix properly restores the interrupt flag and throws RejectedExecutionException (wrapping the original cause), which is semantically precise and avoids violating the concurrency limit that Limited exists to enforce.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of gnodet

@cstamas
cstamas merged commit b749cad into master Jul 24, 2026
21 of 23 checks passed
@cstamas
cstamas deleted the fix-interrupted-exception-1993 branch July 24, 2026 12:03
@github-actions github-actions Bot added this to the 2.0.22 milestone Jul 24, 2026
@github-actions

Copy link
Copy Markdown

@cstamas Please assign appropriate label to PR according to the type of change.

@cstamas cstamas added the bug Something isn't working label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InterruptedException causes task to be silently dropped in SmartExecutor.Limited.submit(Runnable)

4 participants