Generic Send Mail K2 Exception Handler (Send mail on process error/exception)

Hi,

For the last couple of years I've been recommending this as, if not best practice, then minimum practice - i.e. the very least you should be doing when developing processes. 

I realise that many out there are building no-code solutions and thus don't / can't benefit from the above advice.  Just recently on an internal K2 mailing list one of the guys sent around a useful copy&paste block of code to safely attempt sending an email if a process falls to error state.   I can't take credit for this but I wanted to post it here so that all K2 folks who both do and don't do code can benefit.


The ideal location for this code is in the process level exception handler - please see the screen shots below:


First access the process level exception handler wizard:

 

Then enable the Exception handler, tell K2 to log any unhandled exception and put the process instance in to error state - tick all boxes, then access the code view by clicking View Code:

 

Expand theExecuteCode section:

 

Remove the highlighted code:

And paste in the code from the bottom of this blog post:

Make sure you update the email addresses highlighted in red.

Full credit goes to Eugene Jones for the code for this.

Ashley.

Code:

            const string fromAddress = "Administrator@k2demo.local";
            const string toAddress = "BPUser@k2demo.local";

            bool _bFlag = true;
            string _sMessage = string.Empty;
            Exception ex = new Exception("K2Exception");
            object _exContext = null;
            System.Web.Mail.MailMessage _expMail = null;

            try
            {

                K2.AddToErrorLog = K2.Configuration.IsErrorLog;

                K2.AddToServerLog = K2.Configuration.IsServerLog;

                System.Web.Mail.SmtpMail.SmtpServer = K2.StringTable["Mail Server"];

                _expMail = new System.Web.Mail.MailMessage();

                _expMail.From = fromAddress;

                _expMail.To = toAddress;

                // Get the process details

                _expMail.Subject = "Process " + K2.ProcessInstance.Folio + " has gone into error state";

                _sMessage = "Process Folio: " + K2.ProcessInstance.Folio + System.Environment.NewLine + System.Environment.NewLine;

                _sMessage += "Process ID: " + K2.ProcessInstance.ID.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                _sMessage += "Process Fullname: " + K2.ProcessInstance.Process.FullName + System.Environment.NewLine + System.Environment.NewLine;

                _sMessage += "Process Start Date: " + K2.ProcessInstance.StartDate.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                _sMessage += "Process Originator: " + K2.ProcessInstance.Originator.Name + System.Environment.NewLine + System.Environment.NewLine;



                _sMessage += "Process Data: " + System.Environment.NewLine + System.Environment.NewLine;

                foreach (SourceCode.KO.DataField _data in K2.ProcessInstance.DataFields)
                {

                    _sMessage += "Field name: " + _data.Name + "\t" + "Field type: " + _data.FieldType.ToString() + "\t" + "Field value: " + _data.Value.ToString() + System.Environment.NewLine;

                }

                _sMessage += System.Environment.NewLine + System.Environment.NewLine;
               
                // Get Context and details to the component that threw the exception

                switch (K2.ContextType)
                {
                    case SourceCode.KO.ContextType.ClientEvent:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.ClientEventContext)_exContext).ActivityInstanceDestination.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Event Name: " + ((SourceCode.KO.ClientEventContext)_exContext).Event.Name + System.Environment.NewLine;

                            break;
                        }
                       
                    case SourceCode.KO.ContextType.DestinationRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.DestinationRuleContext)_exContext).ActivityInstance.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Destinations: ";

                            foreach (SourceCode.KO.Destination _dest in ((SourceCode.KO.DestinationRuleContext)_exContext).Destinations)
                            {

                                _sMessage += _dest.Name + " [" + _dest.Type.ToString() + "], ";

                            }

                            _sMessage = _sMessage.Substring(0, _sMessage.Length - 2) + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Slot data: ";

                            foreach (string _slotdata in ((SourceCode.KO.DestinationRuleContext)_exContext).SlotInstanceData)
                            {
                                _sMessage += _slotdata + ", ";
                            }

                            _sMessage = _sMessage.Substring(0, _sMessage.Length - 2) + System.Environment.NewLine + System.Environment.NewLine;
                            _sMessage += "Dynamic Queues: " + ((SourceCode.KO.DestinationRuleContext)_exContext).DynamicQueues.ToString() + System.Environment.NewLine + System.Environment.NewLine;
                            _sMessage += "Resolve Queues To Users: " + ((SourceCode.KO.DestinationRuleContext)_exContext).ResolveQueuesToUsers.ToString() + System.Environment.NewLine + System.Environment.NewLine;
                            _sMessage += "Single Instance: " + ((SourceCode.KO.DestinationRuleContext)_exContext).SingleInstance.ToString() + System.Environment.NewLine + System.Environment.NewLine;
                            _sMessage += "Number of slots: " + ((SourceCode.KO.DestinationRuleContext)_exContext).Slots.ToString() + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.EscalationAction:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.EscalationActionContext)_exContext).ActivityInstance.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Redirect: " + ((SourceCode.KO.EscalationActionContext)_exContext).Redirect.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.EscalationRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.EscalationRuleContext)_exContext).ActivityInstance.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.EventEscalationAction:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.EventEscalationActionContext)_exContext).EventInstance.ActivityInstanceDestination.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Event Name: " + ((SourceCode.KO.EventEscalationActionContext)_exContext).EventInstance.Event.Name + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.EventEscalationRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.EventEscalationRuleContext)_exContext).EventInstance.ActivityInstanceDestination.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Event Name: " + ((SourceCode.KO.EventEscalationRuleContext)_exContext).EventInstance.Event.Name + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.EventSucceedingRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.EventSucceedingRuleContext)_exContext).EventInstance.ActivityInstanceDestination.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Event Name: " + ((SourceCode.KO.EventSucceedingRuleContext)_exContext).EventInstance.Event.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Succeeding Rule: " + ((SourceCode.KO.EventSucceedingRuleContext)_exContext).SucceedingRule.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.IPCEvent:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.IPCEventContext)_exContext).ActivityInstanceDestination.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Event Name: " + ((SourceCode.KO.IPCEventContext)_exContext).Event.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "IPC Process: " + ((SourceCode.KO.IPCEventContext)_exContext).Process + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "IPC Connection String: " + ((SourceCode.KO.IPCEventContext)_exContext).ConnectionString + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.LineRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Start Activity Name: " + ((SourceCode.KO.LineRuleContext)_exContext).LineInstance.StartActivityInstance.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Finish Activity Name: " + ((SourceCode.KO.LineRuleContext)_exContext).LineInstance.FinishActivityInstance.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Line Name: " + ((SourceCode.KO.LineRuleContext)_exContext).LineInstance.Line.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Line Rule: " + ((SourceCode.KO.LineRuleContext)_exContext).LineRule.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.PrecedingRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.PrecedingRuleContext)_exContext).ActivityInstance.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Preceeding Rule: " + ((SourceCode.KO.PrecedingRuleContext)_exContext).PrecedingRule.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.ProcessEscalationAction:

                    case SourceCode.KO.ContextType.ProcessEscalationRule:

                    case SourceCode.KO.ContextType.ProcessFinishRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            break;

                        }

                    case SourceCode.KO.ContextType.ProcessStartRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Message: " + ((SourceCode.KO.ProcessStartRuleContext)_exContext).Message + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Start: " + ((SourceCode.KO.ProcessStartRuleContext)_exContext).Start.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            break;

                        }

                    case SourceCode.KO.ContextType.ServerEvent:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.ServerEventContext)_exContext).ActivityInstanceDestination.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Event Name: " + ((SourceCode.KO.ServerEventContext)_exContext).Event.Name + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.StartRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.StartRuleContext)_exContext).ActivityInstance.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            break;

                        }

                    case SourceCode.KO.ContextType.SucceedingRule:
                        {

                            _sMessage += "Exception thrown by: " + K2.ContextType.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            _exContext = K2.ContextObject;

                            _sMessage += "Activity Name: " + ((SourceCode.KO.SucceedingRuleContext)_exContext).ActivityInstance.Activity.Name + System.Environment.NewLine + System.Environment.NewLine;

                            _sMessage += "Succeeding Rule: " + ((SourceCode.KO.SucceedingRuleContext)_exContext).SucceedingRule.ToString() + System.Environment.NewLine + System.Environment.NewLine;

                            break;
                        }
                    default:
                        {
                            break;
                        }
                }

                _sMessage += System.Environment.NewLine + "Exception: " + System.Environment.NewLine;

                // Get the actual exception thrown
                ex = (Exception)K2.ExceptionObject;

                while (_bFlag == true)
                {
                    if (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }

                    else
                    {

                        _sMessage += "\tMessage: " + ex.Message + System.Environment.NewLine;

                        _sMessage += "Stack Trace:" + System.Environment.NewLine;

                        _sMessage += "\t" + "\t" + ex.StackTrace + System.Environment.NewLine + System.Environment.NewLine;

                        _bFlag = false;

                    }
                }

                _expMail.Body = _sMessage;

                System.Web.Mail.SmtpMail.Send(_expMail);

                // Rethrow the original exception to make sure the process goes into error state

                throw new Exception(ex.Message);

            }

            catch (Exception ex2)
            {
                throw new Exception(ex2.Message);
            }

            finally
            {
                ex = null;
                _exContext = null;
                _expMail = null;
            }

 


Posted Tue, Nov 24 2009 8:26 AM by hoshy