{"record":{"id":"4d033b1cd42c26b8","repo":"apache/pulsar","slug":"wraps-underlying-failure-cause-4d033b","errorCode":null,"errorMessage":"(wraps underlying failure cause)","messagePattern":"\\(wraps underlying failure cause\\)","errorType":"exception","errorClass":"PulsarClientException","httpStatus":null,"severity":"error","filePath":"pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/ScalableTopicProducer.java","lineNumber":185,"sourceCode":"\n    @Override\n    public AsyncProducer<T> async() {\n        return asyncView;\n    }\n\n    @Override\n    public void close() throws PulsarClientException {\n        try {\n            closeAsync().get();\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new PulsarClientException(\"Close interrupted\", e);\n        } catch (ExecutionException e) {\n            Throwable cause = e.getCause();\n            if (cause instanceof PulsarClientException pce) {\n                throw pce;\n            }\n            throw new PulsarClientException(cause);\n        }\n    }\n\n    /**\n     * Send a message synchronously with routing. Called by MessageBuilderV5.\n     * Returns a MessageIdV5 that includes the segment ID for ack routing.\n     */\n    MessageIdV5 sendInternal(\n            String key, T value, java.util.Map<String, String> properties,\n            java.time.Instant eventTime, Long sequenceId,\n            java.time.Duration deliverAfter, java.time.Instant deliverAt,\n            java.util.List<String> replicationClusters,\n            org.apache.pulsar.client.api.v5.Transaction txn) throws PulsarClientException {\n\n        PulsarClientException lastError = null;\n        for (int attempt = 0; attempt < SEND_RETRY_MAX_ATTEMPTS; attempt++) {\n            long segmentId = routeMessage(key);\n            try {","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/ScalableTopicProducer.java#L167-L203","documentation":"When closeAsync() completes exceptionally with a non-PulsarClientException cause, close() wraps the underlying cause in a plain PulsarClientException. The message is the cause's toString/inheritance default, so inspect getCause() for the real failure.","triggerScenarios":"closeAsync()'s internal future fails with an unexpected throwable (e.g. NPE, IllegalStateException from segment-producer bookkeeping) rather than a PulsarClientException; the synchronous close() then rethrows it wrapped.","commonSituations":"Internal bugs during segment producer teardown; concurrent close() and routeMessage() on the same producer; broker connection failures surfaced as runtime exceptions from the v4 client.","solutions":["Log/inspect e.getCause() to find the real error; the wrapping exception's own message is not informative.","If the cause is a connection problem, verify broker connectivity and client configuration before retrying close().","Avoid sharing the producer across threads without synchronization so teardown does not race.","If persistent, prefer closeAsync() to observe the original failure type directly."],"exampleFix":"// before\ntry { producer.close(); } catch (PulsarClientException e) { log.error(e.getMessage()); }\n// after\ntry { producer.close(); } catch (PulsarClientException e) { log.error(\"close failed\", e.getCause() != null ? e.getCause() : e); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"static boolean hasCause(Throwable e) { return e != null && e.getCause() != null; }","tryCatchPattern":"try {\n    producer.close();\n} catch (PulsarClientException e) {\n    Throwable cause = e.getCause();\n    log.error(\"Producer close failed\", cause != null ? cause : e);\n}","preventionTips":["Always inspect getCause() on PulsarClientException thrown from close()","Do not close a producer concurrently with sends","Prefer closeAsync() to observe the original failure type"],"tags":["lifecycle","wrapped-exception","pulsar-client"],"backgroundTag":"wrapped-exception-cause","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"}