private void ProcessException(WorkflowErrorEventArgs args, WorkflowRuntime runtime)
 {
     if (!String.IsNullOrEmpty(args.ProcessInstance.ExecutedTimer))
     {
         Log.Error($"Exception::: Timer: {args.Exception.Message}");
         args.ProcessStatus = ProcessStatus.Idled;
     }
     else
     {
         Log.Error($"Exception::: Command: {args.Exception.Message}");
         runtime.SetActivityWithExecution(
             identityId: null,
             impersonatedIdentityId: null,
             parameters: new Dictionary <string, object>(),
             activityToSet: args.ProcessInstance.ProcessScheme.InitialActivity,
             processInstance: args.ProcessInstance,
             doNotSetRunningStatus: true
             );
     }
 }
        private void ProcessException(WorkflowErrorEventArgs args, WorkflowRuntime runtime)
        {
            // Follow recommendation
            // https://workflowengine.io/documentation/scheme/timers/

            var isTimerTriggeredTransitionChain =
                !string.IsNullOrEmpty(args.ProcessInstance.ExecutedTimer) || //for timers executed from main branch
                (args.ProcessInstance.MergedSubprocessParameters != null && //for timers executed from subprocess
                 !string.IsNullOrEmpty(args.ProcessInstance.MergedSubprocessParameters.GetParameter(DefaultDefinitions.ParameterExecutedTimer.Name)?.Value?.ToString()));

            // We have to delay creation of the Bugsnag Client until runtime instead
            // of constructor dependency injection due to crashing on startup
            using (var scope = ServiceProvider.CreateScope())
            {
                var client = scope.ServiceProvider.GetRequiredService <Bugsnag.IClient>();
                client.Notify(args.Exception, (report) =>
                {
                    report.Event.Metadata.Add("details", new Dictionary <string, object>
                    {
                        { "handler", "OnWorkflowError" },
                        { "timer", isTimerTriggeredTransitionChain },
                        { "process-id", args.ProcessInstance.ProcessId },
                        { "schema-code", args.ProcessInstance.SchemeCode },
                        { "schema-id", args.ProcessInstance.SchemeId }
                    });

                    if (args.Exception is ResponseException responseException)
                    {
                        var contentType = new ContentType(responseException.ContentType);
                        var charset     = contentType.CharSet ?? "UTF-8";
                        var encoding    = Encoding.GetEncoding(charset);
                        var content     = encoding.GetString(responseException.RawBytes, 0, responseException.RawBytes.Length);

                        report.Event.Metadata.Add("response", new Dictionary <string, object>
                        {
                            { "content", content },
                            { "content-length", responseException.ContentLength },
                            { "content-type", responseException.ContentType }
                        });
                    }
                });
            }

            if (isTimerTriggeredTransitionChain)
            {
                Log.Error($"Exception::: Timer: {args.Exception.Message}");
                args.SuppressThrow = true;
            }
            else
            {
                Log.Error($"Exception::: Command: {args.Exception.Message}");
                runtime.SetActivityWithExecution(
                    identityId: null,
                    impersonatedIdentityId: null,
                    parameters: new Dictionary <string, object>(),
                    activityToSet: args.ProcessInstance.ProcessScheme.InitialActivity,
                    processInstance: args.ProcessInstance,
                    doNotSetRunningStatus: true
                    );
            }
        }