diff --git a/spring-messaging/src/main/java/org/springframework/messaging/MessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/MessageHandler.java index ac2a3ebbb4f..7eee45192ea 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/MessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/MessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ public interface MessageHandler { /** * Handle the given message. * @param message the message to be handled + * @throws MessagingException if the handler failed to process the message */ void handleMessage(Message message) throws MessagingException; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java index 658f4ba0f34..343876f8e05 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java @@ -38,6 +38,7 @@ import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHandler; +import org.springframework.messaging.MessageHandlingException; import org.springframework.messaging.MessagingException; import org.springframework.messaging.handler.DestinationPatternsMessageCondition; import org.springframework.messaging.handler.HandlerMethod; @@ -395,6 +396,7 @@ public abstract class AbstractMethodMessageHandler if (lookupDestination == null) { return; } + MessageHeaderAccessor headerAccessor = MessageHeaderAccessor.getMutableAccessor(message); headerAccessor.setHeader(DestinationPatternsMessageCondition.LOOKUP_DESTINATION_HEADER, lookupDestination); headerAccessor.setLeaveMutable(true); @@ -454,9 +456,9 @@ public abstract class AbstractMethodMessageHandler handleNoMatch(this.handlerMethods.keySet(), lookupDestination, message); return; } + Comparator comparator = new MatchComparator(getMappingComparator(message)); matches.sort(comparator); - if (logger.isTraceEnabled()) { logger.trace("Found " + matches.size() + " handler methods: " + matches); } @@ -533,16 +535,16 @@ public abstract class AbstractMethodMessageHandler processHandlerMethodException(handlerMethod, ex, message); } catch (Throwable ex) { - if (logger.isErrorEnabled()) { - logger.error("Error while processing message " + message, ex); - } + Exception handlingException = + new MessageHandlingException(message, "Unexpected handler method invocation error", ex); + processHandlerMethodException(handlerMethod, handlingException, message); } } - protected void processHandlerMethodException(HandlerMethod handlerMethod, Exception ex, Message message) { - InvocableHandlerMethod invocable = getExceptionHandlerMethod(handlerMethod, ex); + protected void processHandlerMethodException(HandlerMethod handlerMethod, Exception exception, Message message) { + InvocableHandlerMethod invocable = getExceptionHandlerMethod(handlerMethod, exception); if (invocable == null) { - logger.error("Unhandled exception from message handler method", ex); + logger.error("Unhandled exception from message handler method", exception); return; } invocable.setMessageMethodArgumentResolvers(this.argumentResolvers); @@ -550,7 +552,10 @@ public abstract class AbstractMethodMessageHandler logger.debug("Invoking " + invocable.getShortLogMessage()); } try { - Object returnValue = invocable.invoke(message, ex, handlerMethod); + Throwable cause = exception.getCause(); + Object returnValue = (cause != null ? + invocable.invoke(message, exception, cause, handlerMethod) : + invocable.invoke(message, exception, handlerMethod)); MethodParameter returnType = invocable.getReturnType(); if (void.class == returnType.getParameterType()) { return;