locked
SpeechCompositeActivity & general fault handling RRS feed

  • Question

  • Hi,

     

    Is it possible to add general fault handling procedures into an activity based on a  "SpeechCompositeActivity".

     

    When you create a Custom Activity based on a "SpeechSequenceActivity" you get the option to add FaultHandlers through the Dialog view.  This is not possible when a Custom Activity is based on a "SpeechCompositeActivity".

     

    What is the recommended way of adding a general fault handler so that we can ensure everything is cleared up and the activity is closed correctly.

     

    Thanks

     

    Kevin

    Tuesday, June 19, 2007 10:42 AM

Answers

  • Ah, yes, in this case you are doing the right thing deriving from SpeechCompositeActivity. I assume you've looked at the SupervisedTransfer sample code that does the same thing.

     

    Are you failing to override/implement CancelCore, or doing it wrong? If you throw on the workflow thread and you don't handle it, the workflow runtime will attempt to kill off your workflow. To do that, it will call Cancel in a top-down fashion. Ultimately, your composite activity should have its Cancel method called, and in that you should do a "base.CancelCore(executionContext)" (assuming you've derived from SpeechCompositeActivity.) If your Cancel method doesn't close the activity, the workflow will never be able to terminate and you'll see a hang.

     

    Dan

     

    Tuesday, June 19, 2007 8:12 PM

All replies

  • No, it is not directly possible to add FaultHandlers to a composite activity. A SequenceActivity is a special (derived) type of CompositeActivity that has logic to enable the FaultHandler and CancellationHandler. If you need this functionality within a CompositeActivity, you would need to add it yourself. If you don't do so, the containing SpeechSequence's FaultHandlers will be used.

     

    But I have a question for you: why are you using a CompositeActivity, as opposed to a SpeechSequence? If you are trying to build a custom activity, in most cases deriving from SpeechSequence is the right way to go. Think twice before deriving from SpeechCompositeActivity, because you may be doing so unnecessarily and losing some functionality, as you've seen. And the work involved in scheduling the activation your children is not trivial.

     

    Dan

     

    Tuesday, June 19, 2007 2:37 PM
  • Thanks for the information Dan.

     

    What we've done is build a supervised transfer activity which puts the first (calling) party on hold, calls a second (called) party and asks if they they want to accept the call.  The calls are either connected or the first call is resumed depending on the response from the called party.

     

    I believe using a SpeechCompositeActivity is the best way to perform this sequence of events.

     

    The problem I've had is that if I don't catch an exception (we're in the middle of testing the exception handling within this activity therefore we are introducing exceptions in various places) my code does not close the Activity and the dialog will hang.

    If I could have had a general FaultHandler then I could have ensured the Activity was closed.

     

    I'll have to check through my code and ensure everything is water/exception tight.

     

    Unless there is another way of performing the sequence of activities I require?

     

    Kevin

     

    Tuesday, June 19, 2007 4:38 PM
  • Ah, yes, in this case you are doing the right thing deriving from SpeechCompositeActivity. I assume you've looked at the SupervisedTransfer sample code that does the same thing.

     

    Are you failing to override/implement CancelCore, or doing it wrong? If you throw on the workflow thread and you don't handle it, the workflow runtime will attempt to kill off your workflow. To do that, it will call Cancel in a top-down fashion. Ultimately, your composite activity should have its Cancel method called, and in that you should do a "base.CancelCore(executionContext)" (assuming you've derived from SpeechCompositeActivity.) If your Cancel method doesn't close the activity, the workflow will never be able to terminate and you'll see a hang.

     

    Dan

     

    Tuesday, June 19, 2007 8:12 PM
  • I did base my SupervisedTransferActivity on the sample (with quite a few modifications to allow bargein etc.) therefore I do have a CancelCore method which does call "base.CancelCore".  To stop the dialog from hanging I've added a call to "this.close(null)" to the end of my CancelCore method and this fixes everything.  The SupervisedTransfer sample doesn't have this call to the close method.  Should the example have this call?

     

    Everything is working as I'd expect now.

     

    Thanks

     

    Kevin

     

    Wednesday, June 20, 2007 2:41 PM
  • Hi,

     

    It looks like I spoke too soon.

     

    Things are not working exactly as I expect when an Exception is thrown (though my initial problem has been solved).

     

    We've got a Custom Activity (SupervisedTransferActivity) based on a SpeechCompositeActivity.

    This is used by another Customer Activity (TransferActivity) based on a SpeechSequenceActivity.

    These are compiled into a DLL.

     

    This in turn is used within a WorkFlow to perform transfers.

     

    The WorkFlow contains a FaultHandler which is triggered on the System.Exception FaultType.

    Our "TransferActivity" also contains a FaultHandler which is triggered on the System.Exception FaultType.

     

    When an Exception is thrown within the "SupervisedTransferActivity" the CancelCore is called and the Activity is closed.

    I'd expect the FaultHandler within the "TransferActivity" to be triggered by the Exception but it is not.

    The Exception triggers the FaultHandler within the WorkFlow.

     

    Is there a reason why the FaultHandler within the "TransferActivity" is not triggered when an Exception is thrown within the "SupervisedTransferActivity"?

     

    When an Exception is thrown within the "TransferActivity" the FaultHandler within the "TransferActivity" is triggered as expected, therefore the FaultHandler is active.

     

    Thanks for any help with this.

     

    Kevin

     

     

    Wednesday, June 20, 2007 4:00 PM
  • The problem might be that when the exception is thrown, workflow doesn't actually know that it's thrown by your currently-executing SpeechCompositeActivity. If you have a exception you want thrown, you need to "get back into the right activity" (metaphorically speaking). Try replacing this:

     

    throw new Exception("foo")

     

    with

     

    Close(new Exception("foo")); // invoking SpeechCompositeActivity.Close(Exception error)

     

    and tell me if that fixes it.

     

    If you are not able to catch the exception yourself and re-route it like this, you're out of luck. Although it might be obvious to you that the exception "belongs" to the running SCA, the workflow itself doesn't know that.

     

    Dan

    Thursday, June 21, 2007 7:46 PM
  •  

    Hi Dan,

     

    I've performed various experiments and found that it is possible to pass an exception up to the next level (the "TransferActivity" in my case) using Close(new exception("???")), as long as this is done within the main methods of the CompositeActivity (i.e. not the overridden methods).

     

    What I really need to do is identify the Exception that was thrown which resulted in the CancelCore method to be called and then pass this exception to the next level using the Close(new Exception("???")) call but this does not seem to work.  The Exception is caught at the main WorkFlow level rather than within the Activity itself.

     

    It looks like "I'm out of Luck" and will need to ensure all possible exceptions are caught and dealt with within the CompositeActivity.

     

    Thanks for your help on this.

     

    Kevin

    Tuesday, June 26, 2007 2:05 PM