title: Spring-boot-starter RabbitMQ global error handling
body: <p>I am using spring-boot-starter-amqp 1.4.2.Producer and consumer working fine but sometimes the incoming JSON messages have an incorrect syntax. This results in the following (correct) exception:</p>
  
  <pre><code>org.springframework.amqp.rabbit.listener.ListenerExecutionFailedException: Listener threw exception
  Caused by:  org.springframework.amqp.support.converter.MessageConversionException: Failed to convert Message content
  Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token...
  </code></pre>
  
  <p>In future i may face lot more exceptions. So i want to configure a global error handler so that if there is any exception in any one the consumer i can handle it globally.</p>
  
  <p>Note : In this case message is not at all reached consumer. I want to handle these kind of exceptions globally across the consumer.</p>
  
  <p>Please find the below code :</p>
  
  <p><strong>RabbitConfiguration.java</strong></p>
  
  <pre><code>@Configuration
  @EnableRabbit
  public class RabbitMqConfiguration {
  
      @Autowired
      private CachingConnectionFactory cachingConnectionFactory;
  
      @Bean
      public MessageConverter jsonMessageConverter()
      {
          return new Jackson2JsonMessageConverter();
      }
  
      @Bean
      @Primary
      public RabbitTemplate rabbitTemplate()
      {
          RabbitTemplate template = new RabbitTemplate(cachingConnectionFactory);
          template.setMessageConverter(jsonMessageConverter());
          return template;
      }
  
  }
  </code></pre>
  
  <p><strong>Consumer</strong></p>
  
  <pre><code>@RabbitListener(
          id = "book_queue",
          bindings = @QueueBinding(
                  value = @Queue(value = "book.queue", durable = "true"),
                  exchange = @Exchange(value = "book.exchange", durable = "true", delayed = "true"),
                  key = "book.queue"
          )
      )
  public void handle(Message message) {
  //Business Logic
  }
  </code></pre>
  
  <p>Could anyone please assist me to handle the error handler globally.Your help should be appreciable.</p>
  
  <p><strong>Updated question as per Gary comment</strong></p>
  
  <p>I can able to run your example and getting the expected output as you said, I just want to try few more negative cases based on your example, but i couldn't understand few things,</p>
  
  <pre><code>this.template.convertAndSend(queue().getName(), new Foo("bar"));
  </code></pre>
  
  <p><strong>output</strong></p>
  
  <p>Received: Foo [foo=bar]</p>
  
  <p>The above code is working fine.Now instead of "Foo" i am sending some other bean</p>
  
  <pre><code>this.template.convertAndSend(queue().getName(), new Differ("snack","Hihi","how are you"));
  </code></pre>
  
  <p><strong>output</strong></p>
  
  <p>Received: Foo [foo=null]</p>
  
  <p>The consumer shouldn't accept this message because it is completely a different bean(Differ.class not Foo.class) so i am expecting it should go to "ConditionalRejectingErrorHandler".Why it is accepting wrong payload and printing as null ? Please correct me if i am wrong.</p>
  
  <p><strong>Edit 1 :</strong></p>
  
  <p>Gary, As you said i have set the header "<strong>TypeId</strong>" while sending the message but still consumer can able to convert wrong messages and it is not throwing any error...please find the code below, I have used your code samples and just did the following modifications, </p>
  
  <p><strong>1) Added "__TypeId__" while sending the message,</strong></p>
  
  <pre><code>this.template.convertAndSend(queue().getName(), new Differ("snack","hihi","how are you"),m -&gt; {
          m.getMessageProperties().setHeader("__TypeId__","foo");
          return m;
      }); 
  </code></pre>
  
  <p><strong>2) Added "DefaultClassMapper" in the "Jackson2JsonMessageConverter"</strong></p>
  
  <pre><code>@Bean
  public MessageConverter jsonConverter() {
      Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
      DefaultClassMapper mapper = new DefaultClassMapper();
      mapper.setDefaultType(Foo.class);
      converter.setClassMapper(mapper);
      return new Jackson2JsonMessageConverter();
  }    
  </code></pre>