kfrost

I've been searching and found a couple things here and there but not exactly what I'm looking for.

Scenario is fairly simple, I have some workflows that I'm hosting as webservices. Create a console app that calls into the webservices. However, if an exception is generated inside of the workflow, the client is never passed the exception.

First I'm trying to understand why this is because if I call into a normal webservice, and an exception occurs it is passed back to the client. However in using WF, the client runs as if nothing ever happens.

Seconde, I see the webserviceInput and exception activities but from what I read those are for if you want to catch something specific and send it back to the client but I've also read that any .Net exception not handled will be passed back automatically but I'm not finding that to be the case.

In the web.config, I'm using the manualsheduler which to my understanding means that the workflow runs off the aspnet thread that started the workflow so I'm puzzled why an exception being thrown by this thread isn't passing the exception back to the client thus haulting the execution at the client.

The way it's functioning now, it appears that workflow isn't running off the original aspnet thread and is spinning up it's own.

If that is the case, how do I get unhandled, unexpected exceptions back to the client I'd prefer not to have to use a output such webserviceOutput or webserviceFaulty activities and require the consumer to check on this param before continuing.

If there isn't a problem I'm missing and what I've described is by design, is there a way to say register the ExceptionNotHandled event in the web.config or somewhere else that will cause unhandled exception to be passed back to the client

Thanks.




Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice

kfrost

I've finally figured out what I consider a hack to get this to work. I define a Fault depency property on the parent workflow and then I bind it to fault depency objects on each custom child activiy.

I have 2 custom activities after the webserviceInput and I put an ifelse at the end. Add just a webserviceFault to the false statement and had problems. So added a webserviceoutput for the true statement and now kind of works.

Except, I put a statement to throw an exception in the first activity which sets the fault object of the parent but the second activity continues to run. Surely I don't have to do a conditional statement between every activity.

I still think there has to be a way to where any faults you don't want to handle should just get returned back to the client by default If not is there a way to wire up an event between the parent and child and when the event is fired, the fault is set and in the parent, method automatically ends the workflow and passes the exception to the consumer

Thanks.






Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice


Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice

kfrost

Yes, information was useless in what I'm askingand no where near close to answering this thread.

I think the scenario may be to try and wire up a handle event in the main workflow that when fired, ends terminates the workflow. We have 4 books on the subject and nothing with any real world scenarios and very limited on hosting with webservice.

Thanks.






Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice

Karthik Raman

Workflow can fault(an exception thrown) for many reason beside processing a webservice input; and hence user has to explicitly model it using WebServiceFault activity to choose which exception he wants to send it back to client and which he doesnt.

Having said that if an exception happens while processing webservice request ; i.e between WebService Input & Webservice Output activity; and if it goes unhandled (termination of the workflow); those exceptions should be automatically surfaced back to client as fault.

Irrespective of that; you said client is unaware of exception How can that is possible if exception caused your flow to skip the execution of "webservice output activity"; your client would have atleast got timeout exception back if not fault, from where it is getting response

If you are using One-Way operation; then yes One-Ways are always Fire & Forget.






Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice

Karthik Raman

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

First I'm trying to understand why this is because if I call into a normal webservice, and an exception occurs it is passed back to the client. However in using WF, the client runs as if nothing ever happens

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

In code based model webservice "throw" is used to model sending application fault; besides sending fault that throw doesnt affect state of your service.

In workflow; there is a unique way to model sending application fault(WebserviceFault Activity); imagine a scenario if you recieve a invalid PORequest you want to send application fault to your client; you dont want to terminate your workflow just because you got bad request from client.

Having said that while processing the request; if your workflow encounters exception and it is not handled(eventually causing workflow to terminate) those exceptions are trapped and automatically send to client as fault;

For that to happen make sure exception happens after webservice input but before webservice output;

Exception goes unhandled all the way.

If you have catch handler in your workflow then you should model sending the fault using WebServiceFaultActivity.






Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice

kfrost

Karthik,

That's the questions I'm trying to answer. The setup I have is very simple.

workflow library

activity library

all workflows hosted as webservices.

Create unit tests that have webreferences to the workflow webservices.

In one particular workflow, in the constructor for the workflow I have a type that gets populated from a config file. I put some bad data in the config file and Webconfiguration manager threw an exception and it halted everything and was reported back to the unit test.

I fixed that and created an initialized handler and a completed handler and put threw new exception("test fault")

Run the unit test and it passes successfully. However I attach to the aspnet process and debug and clearly the exception gets thrown but this never makes it back to the client.

I also have two custom activities that run in this workflow. All the do is go to a database and update some data. However if I change their code to where sql throws an exception, say I do this in activity 1 and step through it, I see the exception activity 1 throws but nothing gets passed back to the client and the unit test passes without a problem.

Very sporadic and makes no sense i agree. For the types of exceptions getting throw it was my impression that I didn't even need to use a webserviceFaultactivity.

But I have added one at the end but I have to define fault dependency properties in the parent workflow as well as all the child activities as well as output parameters when I don't want them.

As mentioned I put an ifelse at the end of the activities and now when activity faults, the unit test gets an exception but activity 2 still runs which obviously I don't want.

I don't want to have to put an ifelse between every activity checking for a fault. That would be ridiculous.

Having to define a dependency fault object in every workflow and activity is less than ideal as well.

I'm looking how to do this like a normal .net app. Any child activity has a problem and throws an exception, it should bubble back up to the parent workflow, terminate the remaining activities and then the exception get reported back to the client.

Should be simple to repro what I'm talking about.

Simple workflow, and a custom activity, add the custom activity to the workflow. Then create a unit test that calls the workflow via a webservice. Try a throw statement in the workflow initilize statement. then put a throw statement in your custom activity. Run the unit test and see if it fails with an exception or passes like there wasn't any problem.

Thanks






Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice

kfrost

Karthik,

To add to my example, as mentioned I have 2 activities. The first does does an update to a database and the second one sends notifications when the updates happen.

if the db updates fail because of an exception, obviously I want the workflow to terminate and not send a notification that the record was updated, except out and this exception to make it back to the client.

Most examples of the webservicefaultactivity are of checking input parameters and the most common used is a divide method. The check that the divisor is greater than zero in an ifelse statement and if not the create an exception tha the webservicefaultactivity is bound to.

But what we are doing, we aren't going to check that much on pk's being passed in for the records in the database. however, we want an exception that caused the db update to fail to halt the workflow and the exception make it back to the client/consumer so they know it failed and an idea as to why.

Make sense I've been searching for a week trying to find a real world example of something like this and the best way to do it. I know there has to be a better way than what I've come up with.






Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice

kfrost

This weekend I kind of found a cludgy way of doing this. I defined a fault dependency property of type exception on the parent workflow and then bind this fault to each activity property. (A1 and A2) I then put a try catch statement on the code in each of these and assign the the exception to the fault bound to the parent WF.

Problem is I have to put an if else statement for each activity with webserviceFault for me to get the desired results. If I don't even though A1 throughs a fault A2 still runs when I don't want it through.

I went back and dug through my Apress book which by the way I understand it insinuates this should not be happening.

Exception handling in workflow applications is similar, but there are some differences. If an

exception occurs within workflow or activity code (for instance within an event handler in the workflow

class or a method of a custom activity), you have the same opportunity to catch and handle that

exception. If you handle the exception, the workflow continues to run. If you don¡¯t handle the exception,

the workflow is terminated.

But there are differences in the way exceptions are handled in a workflow application compared

to a traditional .NET application. The most important differences are summarized here and then

discussed:

? An unhandled exception in a workflow terminates the workflow, not the entire application.

? Workflow exception handling is asynchronous.

? Workflow exceptions can be handled in code, or handled declaratively within the workflow

model.

448 CHAPTER 12 ¡ö EXCEPTION AND E RROR HANDLING

An unhandled exception in a workflow won¡¯t terminate the entire application. Instead, an

unhandled exception will terminate the workflow instance that threw the exception.

Not sure what I'm still missing here but all I'm trying to do is throw an exception in A1 or A2 and when this happens the workflow terminates and notifies the client of the problem.






Re: Windows Workflow Foundation Exceptions not making it back to consumer when hosting workflow as a webservice

kfrost

Ok, we've finally figured this out. Initially I was under the impression that using the manual scheduler and hosting with a web service, the workflow and everything in it ran off the aspnet thread that kicked off the workflow. With that being my assumption, I thought that any activity within a workflow if not handled would cause the workflow to end and pass the workflow back to the client. This will happen if you drag a built in code activity from the toolbox onto a workflow.

However, it will not if you but custom activities and add them to the workflow. (Our custom activities are in a project and our workflows are in a separate project.)

For this to happen, we've found you do NOT need a WebserviceFaultHandler to do this, you just need to make sure that any exception thrown in the custom activities gets rethrown in the parent workflow.

To handle this, we added a faulthandler activity to our parent workflow and set it to handle System.Exception. Then we added a code activity with the following code.

private void ThrowExceptionActivity_Execute(object sender, EventArgs e)

{

FaultHandlerActivity fa = ((Activity)sender).Parent as FaultHandlerActivity;

throw fa.Fault;

}

This rethrows the fault that occurred that happened anywhere in the workflow.

In the interface the webserviceInput points to, you need to specify an out or a return value. We choose an out like so:

void SetSomething(int Id, int MappingId, string userId, Guid userGuid, string userName, out string fault);

Of course if you specify an out or return value in the interface you have to add a webserviceOutput activity that passes the out value. We didn't really want this but had to. We tried using just a WebserviceFaultActivity which compiled and worked if you were throwing exceptions but got some unintuitive exception unless we used a webservice output with it.

For the fault value in our webserviceOutput, we just use "" as the value.

If you don't rethrow the exception in the workflow from anything that happened in a custom activity, nothing really makes it back to the client and the other activities run sequential. In our case if A1 fails, the workflow should return the exception to the client and nothing else should run.