# spring cloud stream solace pubsub

**URL:** <https://community.solace.com/t/spring-cloud-stream-solace-pubsub/2006>\
**Category:** Solace Event Broker\
**Tags:** spring-cloud-stream, solacepubsub\
**Created:** [August 27, 2024, 7:13am UTC](https://community.solace.com/t/spring-cloud-stream-solace-pubsub/2006 "2024-08-27T07:13:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kirthi](https://avatars.discourse-cdn.com/v4/letter/k/ec9cab/32.png) [@kirthi](https://community.solace.com/u/kirthi)\
**Post date:** [August 27, 2024, 7:13am UTC](https://community.solace.com/t/spring-cloud-stream-solace-pubsub/2006/1 "2024-08-27T07:13:23Z")

</div>

To handle publish error, using the @serviceActivator annotation.

```kotlin

@ServiceActivator(inputChannel ="topic.errors")  

```

After springboot version 3.3.2 upgrade and spring cloud stream version 2023.0.2 upgrade, the publish errors are not handled by the serviceActivator.

```ada

spring.cloud.stream.solace.bindings.receiveMessage-out-0.producer.error-channel-enabled = true

```

---

<div class="post-metadata">

**Author:** ![kirthi](https://avatars.discourse-cdn.com/v4/letter/k/ec9cab/32.png) [@kirthi](https://community.solace.com/u/kirthi)\
**Post date:** [August 27, 2024, 8:05am UTC](https://community.solace.com/t/spring-cloud-stream-solace-pubsub/2006/2 "2024-08-27T08:05:08Z")

</div>

I am able to replicate the publish error, but the handler is not handling the error message  
{“instant”:{“epochSecond”:1724745793,“nanoOfSecond”:375411000},“thread”:“Context\_2\_ProducerDispatcher”,“level”:“ERROR”,“loggerName”:“org.springframework.integration.handler.LoggingHandler”,“message”:“org.springframework.messaging.MessagingException: Producer received error during publishing (Spring message 6b31cc8d-373f-501d-5282-4c9e082cb33c) at 1724745793361, failedMessage=GenericMessage [payload=byte[15309], headers={contentType=application/json, id=6b31cc8d-373f-501d-5282-4c9e082cb33c, timestamp=1724745784290}]\n\tat com.solace.spring.cloud.stream.binder.util.ErrorChannelSendingCorrelationKey.send(ErrorChannelSendingCorrelationKey.java:59)\n\tat com.solace.spring.cloud.stream.binder.util.JCSMPSessionProducerManager$CloudStreamEventHandler.handleErrorEx(JCSMPSessionProducerManager.java:83)\n\tat com.solacesystems.jcsmp.protocol.nio.impl.ProducerErrorNotification.handleNotification(ProducerErrorNotification.java:53)\n\tat com.solacesystems.jcsmp.protocol.nio.impl.ProducerNotificationDispatcher.eventLoop(ProducerNotificationDispatcher.java:83)\n\tat com.solacesystems.jcsmp.protocol.nio.impl.ProducerNotificationDispatcher.run(ProducerNotificationDispatcher.java:101)\n\tat java.base/java.lang.Thread.run(Thread.java:833)\nCaused by: ((Client name: JQ439QQW19/64450/aac594298ef0262d0001/KbKKSeBpQB local(/10.210.248.200:64633) remote()) - ) com.solacesystems.jcsmp.JCSMPErrorResponseException: 403: Publish ACL Denied - Topic ‘«topicName»’ [Subcode:28]\n\tat com.solacesystems.jcsmp.impl.JCSMPXMLMessageProducer.getAndProcessResponse(JCSMPXMLMessageProducer.java:1530)\n\tat com.solacesystems.jcsmp.impl.JCSMPXMLMessageProducer.handlePubMsgResponse(JCSMPXMLMessageProducer.java:2102)\n\tat com.solacesystems.jcsmp.impl.flow.PubFlowManager.handlePubMsgResponse(PubFlowManager.java:708)\n\tat com.solacesystems.jcsmp.protocol.impl.TcpClientChannel.handleMessage(TcpClientChannel.java:1796)\n\tat com.solacesystems.jcsmp.protocol.impl.TcpClientChannel.onMessage(TcpClientChannel.java:2773)\n\tat com.solacesystems.jcsmp.protocol.smf.SMFFrameHandler.decode(SMFFrameHandler.java:103)\n\tat com.solace.transport.impl.netty.NettyTransportInboundFrameDecoderAdapter.decode(NettyTransportInboundFrameDecoderAdapter.java:29)\n\tat io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530)\n\tat io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469)\n\tat io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)\n\tat io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:289)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)\n\tat io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1473)\n\tat io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1336)\n\tat io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1385)\n\tat io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530)\n\tat io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469)\n\tat io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)\n\tat io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)\n\tat com.solace.transport.handler.SolSSLStatsHandler.channelRead(SolSSLStatsHandler.java:36)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)\n\tat io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)\n\tat io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)\n\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)\n\tat io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)\n\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)\n\t… 1 more\n”,“endOfBatch”:true,“loggerFqcn”:“org.apache.commons.logging.LogAdapter$Log4jLog”,“contextMap”:{},“threadId”:74,“threadPriority”:5,“source”:{“classLoaderName”:“app”,“class”:“org.springframework.core.log.LogAccessor”,“method”:“error”,“file”:“LogAccessor.java”,“line”:250}}

---

<div class="post-metadata">

**Author:** ![kirthi](https://avatars.discourse-cdn.com/v4/letter/k/ec9cab/32.png) [@kirthi](https://community.solace.com/u/kirthi)\
**Post date:** [August 27, 2024, 8:21am UTC](https://community.solace.com/t/spring-cloud-stream-solace-pubsub/2006/3 "2024-08-27T08:21:34Z")

</div>

similar error reported :  
[https://stackoverflow.com/questions/76991394/spring-cloud-stream-4-0-4-producer-error-channel-enabled-property-not-working](https://stackoverflow.com/questions/76991394/spring-cloud-stream-4-0-4-producer-error-channel-enabled-property-not-working)

---

<div class="post-metadata">

**Author:** ![marc](https://yyz1.discourse-cdn.com/solace/user_avatar/community.solace.com/marc/32/2191_2.png) [@marc](https://community.solace.com/u/marc)\
**Post date:** [August 28, 2024, 7:04pm UTC](https://community.solace.com/t/spring-cloud-stream-solace-pubsub/2006/4 "2024-08-28T19:04:55Z")

</div>

Hi @kirthi ,

In Spring Cloud Stream v3.2.5 the way to define an error handler was made more clear. You can now add a `error-handler-definition` to each input binding that will receive the errors that occur.

Learn more in section 10 here (search for “Spring Cloud Stream v3.2.5 or higher”):

> **[Spring Cloud Stream - Beyond the Basics](https://codelabs.solace.dev/codelabs/spring-cloud-stream-beyond/#9)**

.

I would also recommend taking a look at this great blog by @giri which includes some nice diagrams that help ensure developers can understand what’s going on between the error handling options provided by the framework and the Solace binder:

> **[Error Handling when using Spring Cloud Stream Binder for Solace PubSub+ | Solace](https://solace.com/blog/error-handling-spring-cloud-stream-binder-solace-pubsub/)**
>
> Learn how the error-handling features supported by the Spring Cloud Stream framework and the Spring Cloud Stream binder for Solace PubSub+ help you handle error scenarios gracefully in a programmatic manner.

Hope that helps and sorry for the confusion!

---

<div class="post-metadata">

**Author:** ![kirthi](https://avatars.discourse-cdn.com/v4/letter/k/ec9cab/32.png) [@kirthi](https://community.solace.com/u/kirthi)\
**Post date:** [August 29, 2024, 6:46am UTC](https://community.solace.com/t/spring-cloud-stream-solace-pubsub/2006/5 "2024-08-29T06:46:05Z")

</div>

Hi @marc.dipasquale ,

Thanks for replying.

My question is related to explicitly handling the Publish error. The issues could be like ACL issues, spool over quota in the destination topic.

Previously, we have handled publish errors as below,  
@ServiceActivator(inputChannel = " **destination\_topic.errors**")

```typescript

public void handlePublishError(ErrorMessage message) {

```

After spring upgrade, this code is not working.

Checked in this document,

> **[Confirming Message Publication and Acknowledging Receipt with Spring Cloud...](https://solace.com/blog/publication-and-receipt-spring-cloud-stream-binder-solace/)**
>
> How the Spring Cloud Stream Binder for Solace PubSub+ supports message publish confirmation and message acknowledgment.

**IMPORTANT:**

In the current version of the Spring Cloud Stream binder for Solace PubSub+, this annotation-based error handler specification approach is valid and fully supported. However, this will be deprecated in future releases and **adopt a configuration property at the binding level** to specify the error handler.

Could you please give an example what is meant by configuration property at the binding level.

I have tried,

```css

spring.cloud.stream.bindings.receiveMessage-out-0.producer.error-handler-definition:myErrorHandler

```

This handler is not capturing the publish errors.

Now, the fix we have implemented is as below (after spring upgrade),

@ServiceActivator(inputChannel = IntegrationContextUtils.ERROR\_CHANNEL\_BEAN\_NAME)  
public void handlePublishError(ErrorMessage message) {}

But the consumer errors (thrown by the application) also listened by this interceptor.

is there any documentation to understand how to handle only publish errors?

---

<div class="post-metadata">

**Author:** ![Jeff](https://yyz1.discourse-cdn.com/solace/user_avatar/community.solace.com/jeff/32/2797_2.png) [@Jeff](https://community.solace.com/u/Jeff)\
**Post date:** [August 29, 2024, 4:55pm UTC](https://community.solace.com/t/spring-cloud-stream-solace-pubsub/2006/6 "2024-08-29T16:55:07Z")

</div>

Hi @kirthi ,

It seems like `error-handler-definition` doesn’t work for producer bindings in Spring Cloud Stream. I’ve raised an issue to ask about this here:

> <https://github.com/spring-cloud/spring-cloud-stream/issues/2997>
>
> \*\*Describe the issue\*\*
> When the producer error channel is enabled and an \`error…-handler-definition\` is defined for that binding, the error handler doesn't receive any error messages.
> 
> \*\*To Reproduce\*\*
> Steps to reproduce the behavior:
> 1. Create a error handler function like:
> \`\`\`java
> @Bean
> public Consumer\<ErrorMessage\> myErrorHandlerFnc() {
> msg -\> logger.info("failed to publish message {}", msg);
> }
> \`\`\`
> 2. Configure any output binding as follows:
> \`\`\`shell
> spring.cloud.stream.bindings.\<binding-name\>.producer.error-channel-enabled=true
> spring.cloud.stream.bindings.\<binding-name\>.error-handler-definition=myErrorHandlerFnc
> \`\`\`
> 3. Cause the producer binding to throw an exception
> 4. Notice that \`myErrorHandlerFnc\` doesn't receive the error message.
> 
> \*\*Version of the framework\*\*
> Spring Boot: 3.3.2
> Spring Cloud: 2023.0.3
> 
> \*\*Expected behavior\*\*
> \`myErrorHandlerFnc\` to receive error messages from the producer binding.
> 
> \*\*Additional context\*\*
> Looking at \[AbstractMessageChannelBinder.registerErrorInfrastructure(
> ProducerDestination destination, String bindingName)\](https://github.com/spring-cloud/spring-cloud-stream/blob/v4.1.3/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinder.java#L729), it seems like \`subscribeFunctionErrorHandler()\` needs to be called there against the producer binding's error channel.

As an alternative solution, you can try using the Publisher Confirmations feature in the Solace binder to handle publish errors:

> **[solace-spring-cloud/solace-spring-cloud-starters/solace-spring-cloud-stream-star...](https://github.com/SolaceProducts/solace-spring-cloud/tree/master/solace-spring-cloud-starters/solace-spring-cloud-stream-starter#publisher-confirmations)**
>
> An umbrella project containing all Solace projects for Spring Cloud - SolaceProducts/solace-spring-cloud
