{"record":{"id":"ab69f1598c0aae1b","repo":"apache/pulsar","slug":"ex-getmessage","errorCode":null,"errorMessage":"${ex.getMessage()}","messagePattern":"\\$\\{ex\\.getMessage\\(\\)\\}","errorType":"exception","errorClass":"java.util.concurrent.CompletionException","httpStatus":null,"severity":"error","filePath":"pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/PulsarClientV5.java","lineNumber":113,"sourceCode":"        if (transactionTimeout != null) {\n            builder.withTransactionTimeout(transactionTimeout.toMillis(), TimeUnit.MILLISECONDS);\n        }\n        return builder.build().thenApply(v4Txn -> (Transaction) new TransactionV5(v4Txn));\n    }\n\n    @Override\n    public void close() throws PulsarClientException {\n        try {\n            v4Client.close();\n        } catch (org.apache.pulsar.client.api.PulsarClientException e) {\n            throw new PulsarClientException(e.getMessage(), e);\n        }\n    }\n\n    @Override\n    public CompletableFuture<Void> closeAsync() {\n        return v4Client.closeAsync().exceptionally(ex -> {\n            throw new CompletionException(new PulsarClientException(ex.getMessage(), ex));\n        });\n    }\n\n    @Override\n    public void shutdown() {\n        try {\n            v4Client.shutdown();\n        } catch (org.apache.pulsar.client.api.PulsarClientException e) {\n            throw new RuntimeException(e);\n        }\n    }\n}\n","sourceCodeStart":95,"sourceCodeEnd":126,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/PulsarClientV5.java#L95-L126","documentation":"The async closeAsync() maps any exception from the underlying client's close future into a CompletionException wrapping a PulsarClientException built from the original message. Callers observe it as an exceptionally-completed CompletableFuture whose cause is this exception — the graceful close of the v4 client failed.","triggerScenarios":"CompletableFuture returned by PulsarClientV5.closeAsync() completes exceptionally when the wrapped client's closeAsync fails: broker unreachable during producer/consumer teardown, or the client is already closed.","commonSituations":"Closing clients during a network outage; shutdown sequences where closeAsync is chained and the wrapped cause surfaces in logs; tests tearing down clients after brokers were stopped.","solutions":["Handle the exceptionally-completed future: inspect the wrapped PulsarClientException cause for the root failure","Retry closeAsync if the failure was transient (network), or fall back to shutdown() for forceful teardown","Ensure you are not closing the same client twice concurrently"],"exampleFix":"// before\nclient.closeAsync(); // exception ignored or surfaces far away\n// after\nclient.closeAsync().exceptionally(ex -> {\n    log.warn(\"Client close failed\", ex);\n    return null;\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"client.closeAsync().whenComplete((v, ex) -> {\n    if (ex != null) log.warn(\"Async close failed: {}\", ex.getMessage(), ex.getCause());\n});","preventionTips":["Always attach whenComplete/exceptionally to closeAsync futures","Coordinate close and shutdown so neither runs twice","Expect transient network failures during close and retry once if needed"],"tags":["lifecycle","close","async"],"backgroundTag":"client-close-failed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}