1
2
3
4
5
6
7
8
9
10
11 package org.mule;
12
13 import org.mule.api.MuleEvent;
14 import org.mule.api.MuleException;
15 import org.mule.api.MuleMessage;
16 import org.mule.api.endpoint.ImmutableEndpoint;
17 import org.mule.api.routing.OutboundRouter;
18 import org.mule.exception.AbstractMessagingExceptionStrategy;
19 import org.mule.message.DefaultExceptionPayload;
20 import org.mule.session.DefaultMuleSession;
21 import org.mule.transport.NullPayload;
22 import org.mule.util.ObjectUtils;
23
24 import org.apache.commons.lang.exception.ExceptionUtils;
25
26
27
28
29
30
31
32
33
34 public class RouteableExceptionStrategy extends AbstractMessagingExceptionStrategy
35 {
36 private OutboundRouter router;
37
38 private boolean stopFurtherProcessing = true;
39
40
41
42
43 public MuleEvent handleException(Exception e, MuleEvent event)
44 {
45 int currentRootExceptionHashCode = 0;
46 int originalRootExceptionHashCode = 0;
47 MuleMessage msg = null;
48
49 StringBuffer logInfo = new StringBuffer();
50
51 try
52 {
53 logInfo.append("****++******Alternate Exception Strategy******++*******\n");
54 logInfo.append("Current Thread = " + Thread.currentThread().toString() + "\n");
55
56 if (event != null && event.getFlowConstruct() != null)
57 {
58 String serviceName = event.getFlowConstruct().getName();
59 logInfo.append("serviceName = " + serviceName + "\n");
60
61 int eventHashCode = event.hashCode();
62 logInfo.append("eventHashCode = " + eventHashCode + "\n");
63 }
64
65 if (event != null && event.isStopFurtherProcessing())
66 {
67 logInfo.append("MuleEvent stop further processing has been set, This is probably the same exception being routed again. no Exception routing will be performed.\n"
68 + e
69 + "\n");
70 event.getMessage().setPayload(NullPayload.getInstance());
71 event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
72 return event;
73 }
74
75 Throwable root = ExceptionUtils.getRootCause(e);
76 currentRootExceptionHashCode = root == null ? -1 : root.hashCode();
77
78 msg = event == null ? null : event.getMessage();
79
80 if (msg != null)
81 {
82 int msgHashCode = msg.hashCode();
83 logInfo.append("msgHashCode = " + msgHashCode + "\n");
84
85 if (msg.getExceptionPayload() != null)
86 {
87 Throwable t = msg.getExceptionPayload().getRootException();
88 if (t != null && t.hashCode() == currentRootExceptionHashCode)
89 {
90 logInfo.append("*#*#*#*#*\n");
91 logInfo.append("This error has already been handeled, returning without doing anything: "
92 + e.getMessage()
93 + "\n");
94 logInfo.append("*#*#*#*#*\n");
95 originalRootExceptionHashCode = currentRootExceptionHashCode;
96 event.getMessage().setPayload(NullPayload.getInstance());
97 event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
98 return event;
99 }
100 }
101
102 originalRootExceptionHashCode = msg.getIntProperty("RootExceptionHashCode", 0);
103
104 logInfo.append("Original RootExceptionHashCode: " + originalRootExceptionHashCode + "\n");
105 logInfo.append("Current RootExceptionHashCode: " + currentRootExceptionHashCode + "\n");
106
107 if (originalRootExceptionHashCode == 0)
108 {
109 msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);
110 originalRootExceptionHashCode = currentRootExceptionHashCode;
111 }
112 else if (originalRootExceptionHashCode == currentRootExceptionHashCode)
113 {
114 logInfo.append("*#*#*#*#*\n");
115 logInfo.append("This error has already been handeled, returning without doing anything: "
116 + e.getMessage()
117 + "\n");
118 logInfo.append("*#*#*#*#*\n");
119 event.getMessage().setPayload(NullPayload.getInstance());
120 event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
121 return event;
122 }
123 else
124 {
125 msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);
126 }
127 }
128
129 logInfo.append(e.getMessage());
130
131 StackTraceElement[] st = e.getStackTrace();
132 for (int i = 0; i < st.length; i++)
133 {
134 if (st[i].getClassName().equals("org.mule.AlternateExceptionStrategy"))
135 {
136 logger.warn("*#*#*#*#*\n"
137 + "Recursive error in AlternateExceptionStrategy "
138 + e
139 + "\n"
140 + "*#*#*#*#*");
141 event.getMessage().setPayload(NullPayload.getInstance());
142 event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
143 return event;
144 }
145 logger.debug(st[i].toString());
146 }
147 return super.handleException(e, event);
148 }
149 finally
150 {
151 if (event != null && this.stopFurtherProcessing) event.setStopFurtherProcessing(true);
152
153 if (msg != null && currentRootExceptionHashCode != 0
154 && currentRootExceptionHashCode != originalRootExceptionHashCode)
155 msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);
156
157 logInfo.append("****__******Alternate Exception Strategy******__*******\n");
158 logger.debug(logInfo.toString());
159 }
160 }
161
162
163
164
165 public void handleMessagingException(MuleMessage message, Throwable t)
166 {
167 defaultHandler(message, t);
168 routeException(getMessageFromContext(message), (ImmutableEndpoint) null, t);
169 }
170
171
172
173
174 public void handleRoutingException(MuleMessage message, ImmutableEndpoint endpoint, Throwable t)
175 {
176 defaultHandler(message, t);
177 routeException(getMessageFromContext(message), endpoint, t);
178 }
179
180
181
182
183 public void handleLifecycleException(Object component, Throwable t)
184 {
185 logger.error("The object that failed is: \n" + ObjectUtils.toString(component, "null"));
186 handleStandardException(t);
187 }
188
189
190
191
192 public void handleStandardException(Throwable t)
193 {
194 handleTransaction(t);
195 if (RequestContext.getEvent() != null)
196 {
197 handleMessagingException(RequestContext.getEvent().getMessage(), t);
198 }
199 else
200 {
201 logger.info("There is no current event available, routing Null message with the exception");
202 handleMessagingException(new DefaultMuleMessage(NullPayload.getInstance(), muleContext), t);
203 }
204 }
205
206 protected void defaultHandler(MuleMessage message, Throwable t)
207 {
208 if (RequestContext.getEvent() != null && RequestContext.getEvent().getMessage() != null)
209 {
210 RequestContext.getEvent().getMessage().setExceptionPayload(new DefaultExceptionPayload(t));
211 }
212
213 if (message != null) message.setExceptionPayload(new DefaultExceptionPayload(t));
214 }
215
216 protected MuleMessage getMessageFromContext(MuleMessage message)
217 {
218 if (RequestContext.getEvent() != null)
219 {
220 return RequestContext.getEvent().getMessage();
221 }
222 else if (message != null)
223 {
224 return message;
225 }
226 else
227 {
228 return new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
229 }
230 }
231
232
233
234
235 protected void routeException(MuleMessage msg, ImmutableEndpoint failedEndpoint, Throwable t)
236 {
237 MuleMessage contextMsg = null;
238 MuleEvent exceptionEvent = RequestContext.getEvent();
239 contextMsg = exceptionEvent == null ? msg : exceptionEvent.getMessage();
240
241 if (contextMsg == null)
242 {
243 contextMsg = new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
244 contextMsg.setExceptionPayload(new DefaultExceptionPayload(t));
245 }
246
247 if (exceptionEvent == null)
248 {
249 exceptionEvent = new DefaultMuleEvent(contextMsg, failedEndpoint, new DefaultMuleSession(muleContext));
250 }
251
252
253 DefaultMuleMessage messageCopy = new DefaultMuleMessage(contextMsg.getPayload(), contextMsg, muleContext);
254
255
256 try
257 {
258 router.process(exceptionEvent);
259 }
260 catch (MuleException e)
261 {
262 logFatal(messageCopy, e);
263 }
264 }
265
266 public OutboundRouter getRouter()
267 {
268 return router;
269 }
270
271 public void setRouter(OutboundRouter router)
272 {
273 this.router = router;
274 }
275
276 public boolean isStopFurtherProcessing()
277 {
278 return stopFurtherProcessing;
279 }
280
281 public void setStopFurtherProcessing(boolean stopFurtherProcessing)
282 {
283 this.stopFurtherProcessing = stopFurtherProcessing;
284 }
285 }