1. Mule
  2. MULE-4955

Refactor Exception Strategy invocation so we don't get exception strategies invoked twice


    • User impact:
    • Migration Impact:
      People need to know that exceptions will only be handled by the listener closer to where the exception happens.
    • Similar Issues:
      MULE-6490Exception strategy triggered twice
      MULE-4924Exception strategy invoked twice on TransactionTemplate
      MULE-2313Exception Strategy logs error twice
      MULE-5808Mule not invoking exception strategy when an exception is thrown in asynchronous flow
      MULE-6249Custom Exception Strategy class not getting being invoked in a Jetty Inbound Endpoint
      MULE-4927Exception strategy invoked both for connector *and* service exception strategies when exception on sync outbound endpoint
      MULE-6140Custom Exception Strategy class not getting invoked
      MULE-6575There is no way to turn off logging in exception strategy
      MULE-4233Quartz connector ignores exception strategy
      MULE-5438default-exception-strategy within a flow doesn't work as expected


      There are several cases in which exceptions are being handled twice by exception listeners. I worked on MULE-4924 and MULE-4927, but the issue is more general. Issue EE-1968 shows this.

      For example:
      We have this when the exception occurs inside a transformer on the outbound endpoint and we are inside an xa transaction.

      In that use case these two calls are in the stack when the exception is thrown:

      • WebSphereMQMessageDispatcher(AbstractMessageDispatcher).send(MuleEvent) line: 165
        • Exception gets handled and rethrown here at:
          • WebSphereMQMessageDispatcher(AbstractMessageDispatcher).send(MuleEvent) line: 200
      • TransactionTemplate.execute(TransactionCallback) line: 114
        • Exception gets handled and not rethrown here:
          • TransactionTemplate.execute(TransactionCallback) line: 138

      The problem is that we cannot avoid the throwing of the exception inside the AbstractMessageDispatcher because we need that exception for the TransactionTemplate to know there was an exception (for example, to rollback a transaction).
      And in the TransactionTemplate we have no way of telling it the exception was handled or not.

      I think we need some marker on the Exceptions that would tell us when they have been handled.

      The proposed solution:

      The idea is to have some marker on the MuleException and MuleRuntimeException that would let us know if an exception was already handled or not. Probably by making both of them implement a new interface called something like MuleHandleStatusException that would have a isAlreadyHandled() and a setAlreadyHandled(boolean handled).

      We would also have a MuleExceptionHandlingUtil with a method that could be called boolean handledExceptionIfNeeded(ExceptionListener listener, Exception e) that would take care of detecting if somewhere in the causes of that exception there is a MuleHandleStatusException and check its status. It could return true if the exception is handled and false if it was already handled.

      We can then change all the lines similar to this:
      MuleExceptionHandlingUtil.handledExceptionIfNeeded(exceptionListener, e);

      Potential Problems:

      Some decisions made:

      • What should we do if we mark an exception as handled and later someone else in the stack encapsulates it in another exception?
        • We will only handle it once. It won't be rehandled even if encapsulated
      • What do we do with exceptions that are neither MuleException nor MuleRuntimeException (ie, that don't implement MuleHandleStatusException)?
        • This case should be very rare (I've seen a lot of places where we catch Exception and we encapsulate it with some MuleException or another). As we don't have a way of know if it was already handled or not, we will handle it everytime.

        Issue Links



            • Assignee:
              Edu Pereda
              Edu Pereda
            • Votes:
              0 Vote for this issue
              0 Start watching this issue


              • Created: