Пример #1
0
        /// <summary />
        public ZincAggregateException(ActorException leading, ActorAggregateException aggregateException)
            : base(leading?.Message, aggregateException)
        {
            #region Validations

            if (leading == null)
            {
                throw new ArgumentNullException(nameof(leading));
            }

            if (aggregateException == null)
            {
                throw new ArgumentNullException(nameof(aggregateException));
            }

            #endregion

            _leading = leading;
        }
Пример #2
0
        /// <summary />
        public ServiceFaultException AsException()
        {
            ActorException innerException = null;

            if (this.InnerFaults != null && this.InnerFaults.Count > 0)
            {
                if (this.InnerFaults.Count == 1)
                {
                    innerException = this.InnerFaults[0].AsException();
                }
                else
                {
                    var exceptions = this.InnerFaults.Select(x => x.AsException());
                    innerException = new ActorAggregateException(exceptions);
                }
            }

            return(new ServiceFaultException(this.Actor, this.Code, this.Message, innerException));
        }
Пример #3
0
        private static ActorFault[] Walk(Exception exception, bool detailed)
        {
            if (exception == null)
            {
                return(null);
            }


            /*
             * AggregateException, which contains Exception[]
             */
            if (exception is AggregateException)
            {
                AggregateException aex = (AggregateException)exception;
                List <ActorFault>  l   = new List <ActorFault>();

                foreach (Exception iex in aex.InnerExceptions)
                {
                    l.AddRange(Walk(iex, detailed));
                }

                return(l.ToArray());
            }


            /*
             * ActorAggregateException, which contains ActorException[]
             */
            if (exception is ActorAggregateException)
            {
                ActorAggregateException aex = (ActorAggregateException)exception;
                List <ActorFault>       l   = new List <ActorFault>();

                foreach (ActorException iex in aex)
                {
                    l.AddRange(Walk(iex, detailed));
                }

                return(l.ToArray());
            }


            /*
             * ActorException
             */
            if (exception is ActorException)
            {
                ActorException aex = (ActorException)exception;

                ActorFault f = new ActorFault();
                f.Actor         = aex.Actor;
                f.Code          = aex.Code;
                f.Message       = aex.Description;
                f.ExceptionType = aex.GetType().FullName;
                f.InnerFaults   = Walk(aex.InnerException, detailed);

                if (detailed == true)
                {
                    f.StackTrace = aex.StackTrace;
                }

                return(new ActorFault[] { f });
            }


            /*
             * Exception
             */
            if (true)
            {
                ActorFault f = new ActorFault();
                f.Actor         = App.Name;
                f.Code          = 991;
                f.Message       = exception.Message;
                f.ExceptionType = exception.GetType().FullName;
                f.InnerFaults   = Walk(exception.InnerException, detailed);

                if (detailed == true)
                {
                    f.StackTrace = exception.StackTrace;
                }

                return(new ActorFault[] { f });
            }

            // Impossible! :)
        }
Пример #4
0
        /// <summary>
        /// Performs the 'common' workload before and after executing the underlying
        /// method.
        /// </summary>
        /// <param name="context">Execution context.</param>
        /// <param name="request">Request message.</param>
        /// <returns>Response message.</returns>
        public async Task <Rp> RunAsync(ExecutionContext context, Rq request)
        {
            #region Validations

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            #endregion


            /*
             * Where's my request? This can happen, when the user doesn't
             * provide a "{}" during the JSON post.
             */
            if (request == null)
            {
                throw new ZincException(ER.MethodInvoker_RequestIsNull);
            }


            /*
             *
             */
            JournalConfiguration config = ZincConfiguration.Current.Journaling;

            if (config.To == null)
            {
                throw new ZincException(ER.Journaling_NotConfigured);
            }

            ZincJournal journalConfig = ZincConfiguration.Current.Journals.FirstOrDefault(j => j.Name == config.To);

            if (journalConfig == null)
            {
                throw new ZincException(ER.Journaling_JournalNotFound, config.To);
            }

            IExecutionJournal journal;

            try
            {
                journal = Platinum.Activator.Create <IExecutionJournal>(journalConfig.Type);
            }
            catch (ActorException ex)
            {
                throw new ZincException(ER.Journaling_InvalidMoniker, ex, config.To);
            }


            /*
             * Normalize WCF dates, so that they are ALL DateTimeKind = Utc
             * Once normalized, secrefy the message.
             */
            WalkFix(request);
            var jrequest = Secrets.Strip <Rq>(request);


            /*
             * Pre-log
             */
            if (config.Type == MethodLoggingType.PrePost)
            {
                await journal.PreAsync(context, jrequest);
            }


            /*
             * Validate
             */
            ValidationResult vr;

            try
            {
                vr = Validator.Validate <Rq>(request);
            }
            catch (Exception ex)
            {
                var vex = new ZincException(ER.MethodInvoker_RequestValidate, ex, request.GetType().FullName);
                context.MomentEnd = PreciseDateTime.UtcNow;

                if (config.Type == MethodLoggingType.PrePost)
                {
                    await journal.PostAsync(context, null, vex);
                }
                else
                {
                    await journal.FullAsync(context, jrequest, null, vex);
                }

                throw vex;
            }

            if (vr.IsValid == false)
            {
                ActorAggregateException agex = new ActorAggregateException(vr.Errors);

                var vex = new ZincException(ER.MethodInvoker_RequestInvalid, agex, request.GetType().FullName);
                context.MomentEnd = PreciseDateTime.UtcNow;

                if (config.Type == MethodLoggingType.PrePost)
                {
                    await journal.PostAsync(context, null, vex);
                }
                else
                {
                    await journal.FullAsync(context, jrequest, null, vex);
                }

                throw vex;
            }


            /*
             *
             */
            T method = System.Activator.CreateInstance <T>();


            /*
             * Run
             */
            Rp response;

            try
            {
                response = await method.RunAsync(context, request);
            }
            catch (ActorException ex)
            {
                context.MomentEnd = PreciseDateTime.UtcNow;

                if (config.Type == MethodLoggingType.PrePost)
                {
                    await journal.PostAsync(context, null, ex);
                }
                else
                {
                    await journal.FullAsync(context, jrequest, null, ex);
                }

                throw;
            }
            catch (AggregateException ex)
            {
                if (ex.InnerExceptions.Count == 1 && ex.InnerExceptions[0] is ActorException)
                {
                    var aex = (ActorException)ex.InnerExceptions[0];

                    context.MomentEnd = PreciseDateTime.UtcNow;

                    if (config.Type == MethodLoggingType.PrePost)
                    {
                        await journal.PostAsync(context, null, aex);
                    }
                    else
                    {
                        await journal.FullAsync(context, jrequest, null, aex);
                    }

                    // Yes, this will re-write exception stack :-(
                    throw aex;
                }
                else if (ex.InnerExceptions.All(x => x is ActorException) == true)
                {
                    ActorAggregateException agg = new ActorAggregateException(ex.InnerExceptions.Select(x => x as ActorException));
                    var uex = new ZincAggregateException(ex.InnerExceptions[0] as ActorException, agg);

                    context.MomentEnd = PreciseDateTime.UtcNow;

                    if (config.Type == MethodLoggingType.PrePost)
                    {
                        await journal.PostAsync(context, null, uex);
                    }
                    else
                    {
                        await journal.FullAsync(context, jrequest, null, uex);
                    }

                    throw uex;
                }
                else
                {
                    var uex = new ZincException(ER.MethodInvoker_UnhandledException, ex, typeof(T).FullName, ex.Message);

                    context.MomentEnd = PreciseDateTime.UtcNow;

                    if (config.Type == MethodLoggingType.PrePost)
                    {
                        await journal.PostAsync(context, null, uex);
                    }
                    else
                    {
                        await journal.FullAsync(context, jrequest, null, uex);
                    }

                    throw uex;
                }
            }
            catch (Exception ex)
            {
                var uex = new ZincException(ER.MethodInvoker_UnhandledException, ex, typeof(T).FullName, ex.Message);

                context.MomentEnd = PreciseDateTime.UtcNow;

                if (config.Type == MethodLoggingType.PrePost)
                {
                    await journal.PostAsync(context, null, uex);
                }
                else
                {
                    await journal.FullAsync(context, jrequest, null, uex);
                }

                throw uex;
            }


            /*
             * We always expect a response: we should never accept a null response!
             */
            if (response == null)
            {
                throw new ZincException(ER.MethodInvoker_ResponseIsNull, typeof(T).FullName);
            }


            /*
             *
             */
            WalkFix(response);
            var jresponse = Secrets.Strip <Rp>(response);


            /*
             * Validate
             */
            try
            {
                vr = Validator.Validate <Rp>(response);
            }
            catch (Exception ex)
            {
                var vex = new ZincException(ER.MethodInvoker_ResponseValidate, ex, request.GetType().FullName);
                context.MomentEnd = PreciseDateTime.UtcNow;

                if (config.Type == MethodLoggingType.PrePost)
                {
                    await journal.PostAsync(context, jresponse, vex);
                }
                else
                {
                    await journal.FullAsync(context, jrequest, jresponse, vex);
                }

                throw vex;
            }

            if (vr.IsValid == false)
            {
                ActorAggregateException agex = new ActorAggregateException(vr.Errors);
                var vex = new ZincException(ER.MethodInvoker_ResponseInvalid, agex, request.GetType().FullName);

                context.MomentEnd = PreciseDateTime.UtcNow;

                if (config.Type == MethodLoggingType.PrePost)
                {
                    await journal.PostAsync(context, jresponse, vex);
                }
                else
                {
                    await journal.FullAsync(context, jrequest, jresponse, vex);
                }

                throw vex;
            }


            /*
             * Post-log
             */
            context.MomentEnd = PreciseDateTime.UtcNow;

            if (config.Type == MethodLoggingType.PrePost)
            {
                await journal.PostAsync(context, jresponse, null);
            }
            else
            {
                await journal.FullAsync(context, jrequest, jresponse, null);
            }

            return(response);
        }