locked
Service not returning Fault when Exception is thrown RRS feed

  • Question

  • Hello,

     

    I have some strange behavioral in my test-services when throwing an exception:

    The message handler (DoAHandler) in Service C is throwing an exception, but not sending a fault over the response port. As the handler is marked 'Exclusive', it can never receive any messages again.

    See Code:

     

    Code Snippet

    public class TestServiceCService : DsspServiceBase

    {

    ///

    /// _state

    ///

    private TestServiceCState _state = new TestServiceCState();

    ///

    /// _main Port

    ///

    [ServicePort("/testservicec", AllowMultipleInstances=false)]

    private TestServiceCOperations _mainPort = new TestServiceCOperations();

     

    ///

    /// Default Service Constructor

    ///

    public TestServiceCService(DsspServiceCreationPort creationPort) :

    base(creationPort)

    {

    }

     

    ///

    /// Service Start

    ///

    protected override void Start()

    {

      base.Start();

      // Add service specific initialization here.

    }

     

     

    [ServiceHandler(ServiceHandlerBehavior.Exclusive)]

    public virtual IEnumerator<ITask> DoAHandler(DoA doA)

    {

      LogInfo("Getting call from a, throwing Exception");

      throw new Exception("Test-Exception");

      doA.ResponsePort.Post(DefaultUpdateResponseType.Instance);

    }

    }

     

     

    The DoAHandler is invoked by demanding the state of Service A (e.g. via the web-browser):

    Code Snippet

    public class TestServiceAService : DsspServiceBase

    {

    /// <summary>

    /// _state

    /// </summary>

    private TestServiceAState _state = new TestServiceAState();

    /// <summary>

    /// _main Port

    /// </summary>

    [ServicePort("/testservicea", AllowMultipleInstances=false)]

    private TestServiceAOperations _mainPort = new TestServiceAOperations();

     

    [Partner("C", Contract = c.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]

    private c.TestServiceCOperations _cPort = new c.TestServiceCOperations();

     

    /// <summary>

    /// Default Service Constructor

    /// </summary>

    public TestServiceAService(DsspServiceCreationPort creationPort) :

    base(creationPort)

    {

    }

    /// <summary>

    /// Service Start

    /// </summary>

    protected override void Start()

    {

      base.Start();

      // Add service specific initialization here.

    }

     

    [ServiceHandler(ServiceHandlerBehavior.Concurrent)]

    public virtual IEnumerator<ITask> GetHandler(Get get)

    {

      yield return Arbiter.Choice(

        _cPort.DoA(),

        delegate(DefaultUpdateResponseType resp)

        {

          LogInfo("Receifed positive answer from Service C");

        },

        delegate(Fault f)

        {

          LogError("Received fault from Service C");

        }

      );

      get.ResponsePort.Post(_state);

      yield break;

    }

    }

     

     

     

    The interesting thing is that Service A receives no answer at all!

    I also created other services, where an fault is sent back when an exception is thrown, so I have no idea what I have done wrong in this case!

     

    Can someone help?

     

    Monday, September 3, 2007 3:41 PM

Answers

  •  

    Hi, i dont see this error so i cant exaplin why the causality does not kick in. As you mention in other services it works fine (including all hours). At this point i would ask you to send me the csproj files (through email) for the services involved and i will try to reproduce locally.

     

    the quick work around ofcourse is to use try/catch in your handler and do the manual fault conversion using Fault.FromException(ex)

     

    thanx

    g

    Tuesday, September 18, 2007 3:16 AM

All replies

  • Hi, can you actually talk to the service? if you dont throw an exception, do you receive the UpdateResponse? If you do, then indeed something wierd is going and i need to dig in to find out. The code as written seems fine and we test this scenario (automatic fault propagation) as part of our regualr test suite.

     

    g

    Tuesday, September 4, 2007 7:34 PM
  • If I comment out the "throw new Exception("Test-Exception");" line, I receive an answer from that service (after adding a yield break at the end of the method).

    I'm a bit confused, because in my motion planning service, I receive a fault from the transformation service when an exception is thrown (e.g. if the desired destination point is out of the working range of the robot arm). So I don't understand why it is not working in this really simple example...

    Friday, September 7, 2007 8:09 AM
  • You might be running into a compiler issue. If you add a yield break statement, does the exception get handled ok?

    can you please include the console/debug output you see when the exception is thrown?

    Friday, September 7, 2007 2:19 PM
  • No, after adding the yield  break statement, no fault is returned. The Handler in Service C now looks like this:

    Code Snippet

    [ServiceHandler(ServiceHandlerBehavior.Exclusive)]

    public virtual IEnumerator<ITask> DoAHandler(DoA doA)

    {

      LogInfo("Getting call from service A, throwing Exception");

      throw new Exception("Test-Exception");

      doA.ResponsePort.Post(DefaultUpdateResponseType.Instance);

      yield break;

    }

     

    The code in service A that calls the handler from service C hasn't changed:

    Code Snippet

    [ServiceHandler(ServiceHandlerBehavior.Concurrent)]

    public virtual IEnumerator<ITask> GetHandler(Get get)

    {

      yield return Arbiter.Choice(

        _cPort.DoA(),

        delegate(DefaultUpdateResponseType resp)

        {

          LogInfo("Received positive answer from Service C");

        },

        delegate(Fault f)

        {

          LogError("Received fault from Service C");

        }

      );

      get.ResponsePort.Post(_state);

      yield break;

    }

     

     

     

    And generates the following Output:

    Code Snippet

    * Manifest load complete [09/17/2007 10:33:32][http://pc40493:50000/manifestloaderclient]

    * Service uri: [09/17/2007 10:33:37][http://pc40493:50000/testservicec]

    * Service uri: [09/17/2007 10:33:37][http://pc40493:50000/testservicea]

    "dsshost.exe" (Verwaltet): "tamdq99h" geladen, keine Symbole geladen.

    "dsshost.exe" (Verwaltet): "2sg73lq5" geladen, keine Symbole geladen.

    * Getting call from service A, throwing Exception [09/17/2007 10:33:53][http://pc40493:50000/testservicec]

    Eine Ausnahme (erste Chance) des Typs "System.Exception" ist in TestServiceC.Y2007.M08.dll aufgetreten.

    *** "TaskExecutionWorker:HandleException": Exception:System.Exception: Test-Exception

    bei KUKA.Test.C.TestServiceCService.d__2.MoveNext() in C:\Microsoft Robotics Studio (1.5)\samples\MyTest\TestServiceC\TestServiceC.cs:Zeile 75.

    bei Microsoft.Ccr.Core.TaskExecutionWorker.ExecuteTask(ITask& currentTask, DispatcherQueue p)

    bei Microsoft.Ccr.Core.TaskExecutionWorker.ExecutionLoop()

    Monday, September 17, 2007 8:40 AM
  •  

    Hi, i dont see this error so i cant exaplin why the causality does not kick in. As you mention in other services it works fine (including all hours). At this point i would ask you to send me the csproj files (through email) for the services involved and i will try to reproduce locally.

     

    the quick work around ofcourse is to use try/catch in your handler and do the manual fault conversion using Fault.FromException(ex)

     

    thanx

    g

    Tuesday, September 18, 2007 3:16 AM