View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.exception;
8   
9   import org.mule.RequestContext;
10  import org.mule.api.MuleContext;
11  import org.mule.api.exception.SystemExceptionHandler;
12  import org.mule.context.notification.ExceptionNotification;
13  import org.mule.message.DefaultExceptionPayload;
14  import org.mule.transport.AbstractConnector;
15  import org.mule.transport.ConnectException;
16  
17  import java.lang.reflect.InvocationTargetException;
18  
19  /**
20   * Log exception, fire a notification, and clean up transaction if any.
21   */
22  public class DefaultSystemExceptionStrategy extends AbstractExceptionListener implements SystemExceptionHandler
23  {
24      /** 
25       * For IoC only 
26       * @deprecated Use DefaultSystemExceptionStrategy(MuleContext muleContext) instead 
27       */
28      public DefaultSystemExceptionStrategy()
29      {
30          super();
31      }
32      
33      public DefaultSystemExceptionStrategy(MuleContext muleContext)
34      {
35          super();
36          setMuleContext(muleContext);
37      }
38  
39      public void handleException(Exception e)
40      {
41          AbstractConnector connector = null;
42  
43          // unwrap any exception caused by using reflection apis, but only the top layer
44          if (e instanceof InvocationTargetException)
45          {
46              Throwable t = e.getCause();
47              // just because API accepts Exception, not Throwable :\
48              e = t instanceof Exception ? (Exception) t : new Exception(t);
49          }
50  
51          if (enableNotifications)
52          {
53              fireNotification(new ExceptionNotification(e));
54          }
55  
56          if (e instanceof ConnectException &&
57              // Make sure the connector is not already being reconnected by another receiver thread
58              ((AbstractConnector) ((ConnectException) e).getFailed()).isReconnecting() == false)
59          {
60              logger.info("Exception caught is a ConnectException, attempting to reconnect...");
61              connector = (AbstractConnector) ((ConnectException) e).getFailed();
62              connector.setReconnecting(true);
63              try
64              {
65                  logger.debug("Disconnecting " + connector.getName());
66                  connector.disconnect();
67              }
68              catch (Exception e1)
69              {
70                  logger.error(e1.getMessage());
71              }
72          }
73  
74          logException(e);
75          
76          handleTransaction(e);
77  
78          if (RequestContext.getEvent() != null)
79          {
80              RequestContext.setExceptionPayload(new DefaultExceptionPayload(e));
81          }
82          
83          if (connector != null)
84          {
85              // Reconnect (retry policy will go into effect here if configured)
86              try
87              {
88                  logger.debug("Reconnecting " + connector.getName());
89                  connector.connect();
90                  connector.setReconnecting(false);
91              }
92              catch (Exception e2)
93              {
94                  logger.error(e2.getMessage());
95              }
96          }
97      }
98  }