{"record":{"id":"671e94af0ef019b9","repo":"alibaba/canal","slug":"stop-rabbitmq-producer-error","errorCode":null,"errorMessage":"Stop RabbitMQ producer error","messagePattern":"Stop RabbitMQ producer error","errorType":"exception","errorClass":"CanalException","httpStatus":null,"severity":"warning","filePath":"connector/rabbitmq-connector/src/main/java/com/alibaba/otter/canal/connector/rabbitmq/producer/CanalRabbitMQProducer.java","lineNumber":216,"sourceCode":"            channel.basicPublish(rabbitMQProperties.getExchange(),\n                queueName,\n                MessageProperties.PERSISTENT_TEXT_PLAIN,\n                message);\n        } catch (Throwable e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    @Override\n    public void stop() {\n        logger.info(\"## Stop RabbitMQ producer##\");\n        try {\n            this.channel.close();\n            this.connect.close();\n        } catch (AlreadyClosedException ex) {\n            logger.error(\"Connection is already closed\", ex);\n        } catch (IOException | TimeoutException ex) {\n            throw new CanalException(\"Stop RabbitMQ producer error\", ex);\n        } finally {\n            super.stop();\n        }\n    }\n}\n","sourceCodeStart":198,"sourceCodeEnd":222,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/connector/rabbitmq-connector/src/main/java/com/alibaba/otter/canal/connector/rabbitmq/producer/CanalRabbitMQProducer.java#L198-L222","documentation":"Thrown by CanalRabbitMQProducer.stop when channel.close()/connect.close() raise IOException or TimeoutException during producer shutdown. AlreadyClosedException is caught separately and only logged, so this error specifically means the close failed on a connection/channel that was (at the time) believed open.","triggerScenarios":"this.channel.close() or this.connect.close() at lines 211-212 throw IOException/TimeoutException. Causes: broker/network dropped during shutdown so the close handshake fails or times out; a resource-level error left the channel in a recoverable-but-not-cleanly-closable state.","commonSituations":"Stopping the producer right as the broker becomes unreachable; slow broker causing close timeout; the auto-recovery client mid-reconnect during stop.","solutions":["Like other shutdown errors, prefer logging over throwing — the producer is stopping anyway.","If you must propagate, ensure callers treat producer-stop failures as non-fatal cleanup noise.","Ensure super.stop() still runs (it is in finally) so connector lifecycle stays consistent even when close fails."],"exampleFix":"// before\n} catch (IOException | TimeoutException ex) {\n    throw new CanalException(\"Stop RabbitMQ producer error\", ex);\n} finally {\n    super.stop();\n}\n\n// after — best-effort close, always run super.stop()\ntry {\n    this.channel.close();\n    this.connect.close();\n} catch (AlreadyClosedException ex) {\n    logger.error(\"Connection is already closed\", ex);\n} catch (IOException | TimeoutException ex) {\n    logger.warn(\"Stop RabbitMQ producer error (best-effort)\", ex);\n} finally {\n    super.stop();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    this.channel.close();\n    this.connect.close();\n} catch (AlreadyClosedException ex) {\n    logger.error(\"Connection is already closed\", ex);\n} catch (IOException | TimeoutException ex) {\n    logger.warn(\"Stop RabbitMQ producer error (best-effort)\", ex);\n} finally {\n    super.stop();\n}","preventionTips":["Treat producer-stop failures as non-fatal cleanup.","Always run super.stop() in finally so connector lifecycle stays consistent.","Do not retry producer close after AlreadyClosedException."],"tags":["rabbitmq","producer","shutdown","canal-connector","lifecycle"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}