{"record":{"id":"f21c77c9d3b76510","repo":"apache/pulsar","slug":"runtimeexception","errorCode":null,"errorMessage":"RuntimeException","messagePattern":"RuntimeException","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerAuditorManager.java","lineNumber":94,"sourceCode":"\n        synchronized (this) {\n            leaderElectionState = les;\n        }\n\n        while (true) {\n            try {\n                synchronized (this) {\n                    if (sessionExpired) {\n                        throw new IllegalStateException(\"Zookeeper session expired, give up to become auditor.\");\n                    }\n                    if (leaderElectionState == LeaderElectionState.Leading) {\n                        return;\n                    } else {\n                        wait();\n                    }\n                }\n            } catch (InterruptedException e) {\n                throw new RuntimeException(e);\n            }\n        }\n    }\n\n    @Override\n    public BookieId getCurrentAuditor() {\n        return leaderElection.getLeaderValue()\n                .join()\n                .map(BookieId::parse)\n                .orElse(null);\n    }\n\n    @Override\n    public void close() throws Exception {\n        leaderElection.close();\n        coordinationService.close();\n    }\n}","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerAuditorManager.java#L76-L112","documentation":"tryToBecomeAuditor() blocks in wait() until leadership is acquired or the session expires. If the waiting thread is interrupted, the InterruptedException is wrapped in a RuntimeException and rethrown, since the method signature has no checked exceptions. This indicates the thread was interrupted (e.g., during broker shutdown) while waiting to become auditor.","triggerScenarios":"Calling tryToBecomeAuditor() on a thread that gets interrupted (Thread.interrupt()) while parked in wait() inside the leadership loop — typically during broker shutdown, executor termination, or manual thread cancellation.","commonSituations":"Broker graceful shutdown interrupting the audit-election thread; unit tests cancelling futures/threads; thread pool shutdownNow() during redeployment.","solutions":["This is expected during shutdown — treat it as benign and stop the election attempt rather than retrying on the same thread.","If it occurs outside shutdown, audit who interrupts the thread and fix the lifecycle management of the auditor-election thread.","On receiving it, check Thread.currentThread().isInterrupted() / reassert interrupt status in surrounding lifecycle code.","Run the election on a dedicated daemon thread with a well-defined shutdown path instead of an ad-hoc thread."],"exampleFix":"// before\ncoordinator.tryToBecomeAuditor();\n// after\ntry {\n    coordinator.tryToBecomeAuditor();\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof InterruptedException) {\n        Thread.currentThread().interrupt();\n        LOG.info(\"Auditor election interrupted, stopping\");\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Run election on a dedicated thread and check interrupt state first\nif (Thread.currentThread().isInterrupted()) {\n    return; // do not start election on an interrupted thread\n}","typeGuard":null,"tryCatchPattern":"try {\n    coordinator.tryToBecomeAuditor();\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof InterruptedException) {\n        Thread.currentThread().interrupt(); // restore status and stop election\n    } else {\n        throw e;\n    }\n}","preventionTips":["Use a dedicated daemon thread for auditor election with explicit shutdown","Avoid shutdownNow() on threads that may be parked in the election loop","Treat unexpected interrupts as lifecycle bugs and trace the interrupting component","During shutdown, prefer cancel-on-flag over interrupt where possible"],"tags":["interruption","threading","leader-election"],"backgroundTag":"thread-interrupted","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}