views:

553

answers:

3

What is the best way to get error messages from a WF4 workflow back to a hosting ASP.NET MVC application? I need the workflow to not terminate, but continue to be active, and then pass a message back to the hosting app regarding the error, so the user can take an alternative action, but I'm not sure how to do that.

A: 

Three ways that I can think of...

WorkflowApplication.OnUnhandledException is there to let you know when an unhandled exception is thrown, but I'm not sure if you can recover from this. Doesn't seem like a good road to go down.

WorkflowApplication.PersistableIdle lets you know when a workflow activity has created a bookmark and idled the workflow. At this point the workflow is waiting for you to return with more information to pass back into the workflow when you resume from the bookmark. This might be your best bet as it is relatively simple to implement and use.

Another twist on this is to create an extension that your activities can get from the workflow context. Extensions give you a more flexible way to communicate outside of the workflow, although you have to code them up and ensure they work as expected. Bookmark + extension would be your most flexible option.

Will
+1  A: 

In order to keep your workflow alive you need to catch the exception in your workflow. Add a TryCatch activity to you workflow and in a Catch block you can use either a Send or a custom activity to send the data to the host application.

The one exception is to use the WorkflowApplication.OnUnhandledException with persistence and specify abort. In that case the in memory state of the workflow is just removed and the workflow can be reloaded for the last persisted state. If you go this way you need to make sure, using the Perist activity, that your workflow is saved whenever something that cannot be redone.

Maurice
Maurice, my Workflow currently is not a WCF workflow (XAMLX), does it need to be to use the Send activity you describe above?
Russ Clark
No there is no need to use the Send. Any custom activity that send data to the host is fine. BTW the Send activity uses WCF messaging but can be used from any workflow host, its the Receive activity that needs the WorkflowServiceHost.
Maurice
OK, I've created a custom activity that just gets the error message from the TryCatch and then assigns that to an OutArgument, but I can't see how to get the value of the OutArgument in my hosting app. I'm trying to use WorkflowApplication since I also have bookmarks that need to be resumed, but I've only seen output from the workflow when using the WorkflowInvoker and then getting the output Dictionary<string,object> back from it. Is there any way to get data back from WorkflowApplication?
Russ Clark
The WorkflowApplication has a Completed property. Point it to some function and the argument will contain a the same Outputs dictionary with the result.
Maurice
OK, Thanks, but how can I get data back if the workflow hasn't yet completed? I'm talking about exception handling for an error that occurs while in the middle of processing the workflow, and in the activity where the workflow fault occurs you said I could add a TryCatch, and then in the catch have a custom activity to send data back to the host, but the workflow has not yet completed in this scenario.
Russ Clark
...and this is where activity tracking comes into play
James Alexander
The custom activity has access to the workflow variables in scope. It can just take whatever is needed and send it somewhere. Either use WCF or just insert it into a database. Its just another activity and can do whatever you want, including waiting for a response.
Maurice
Sorry, I still don't understand. Are you saying that if I resume a bookmark and the bookmark starts a custom activity, and the custom activity hits a fault, say a database error occurred, then the custom activity has no way to directly communicate back to the WorkflowApplication that resumed the bookmark and send information back? I'm thinking I would like to send at least the error message back to the hosting app, but I would like to avoid logging to a database or communicating via a Send activity and WCF if possible.
Russ Clark
Resuming a bookmark, like pretty much everything else in WF, is an asynchronous action. It might happen immediately but could also happen later in a real busy system. And with an async action there is no result to return. All you can do is send another message somewhere.
Maurice
A: 

TryCatch is not really enough when it comes to WF4. Also, handling the UnhandledException event from your workflow host doesn't really tell you much about which activity failed and why.

A suggested approapch is to use TryCatch and Activity tracking within WF4. A good summary of this can be found here: http://msmvps.com/blogs/theproblemsolver/archive/2009/11/27/trycatch-activity-in-wf4.aspx

You can extend your workflow host with Tracking participants and with a catch handler that encapsulates your activity that might fault, handle the exception and create a new TrackingRecord that can better illustrate what happened.

James Alexander
The tracking extension is only required if you need to know which activity caused the error. The TryCatch will do just fine in catching the error and telling you what went wrong, its only the where that is missing.
Maurice
That was more or less my point. I should've been more clear. Suffering from a wicked sinus infection and didn't think my answer out too clearly.
James Alexander