Example #1
0
        public static ErrorStack GenerateErrorStack(bool generateId = false, string id = null, string organizationId = null, string projectId = null) {
            var stack = new ErrorStack {
                Id = id.IsNullOrEmpty() ? generateId ? ObjectId.GenerateNewId().ToString() : null : id,
                OrganizationId = organizationId.IsNullOrEmpty() ? TestConstants.OrganizationId : organizationId,
                ProjectId = projectId.IsNullOrEmpty() ? TestConstants.ProjectIds.Random() : projectId,
                Title = RandomHelper.GetPronouncableString(RandomHelper.GetRange(5, 50))
            };

            for (int i = 0; i < RandomHelper.GetRange(0, 5); i++) {
                string tag = RandomHelper.GetPronouncableString(RandomHelper.GetRange(5, 15));
                while (stack.Tags.Contains(tag))
                    tag = RandomHelper.GetPronouncableString(RandomHelper.GetRange(5, 15));

                stack.Tags.Add(tag);
            }

            return stack;
        }
        public static WebHookErrorStack FromErrorStack(ErrorStack stack, IProjectRepository projectRepository, IOrganizationRepository organizationRepository) {
            if (stack == null)
                throw new ArgumentNullException("stack");

            if (projectRepository == null)
                throw new ArgumentNullException("projectRepository");

            if (organizationRepository == null)
                throw new ArgumentNullException("organizationRepository");

            var project = projectRepository.GetByIdCached(stack.ProjectId);
            if (project == null)
                throw new ArgumentException("ProjectId not found.");

            var organization = organizationRepository.GetByIdCached(stack.OrganizationId);
            if (organization == null)
                throw new ArgumentException("OrganizationId not found.");

            return new WebHookErrorStack {
                Id = stack.Id,
                Title = stack.Title,
                Description = stack.Description,
                Tags = stack.Tags,
                RequestPath = stack.SignatureInfo.ContainsKey("Path") ? stack.SignatureInfo["Path"] : null,
                Type = stack.SignatureInfo.ContainsKey("ExceptionType") ? stack.SignatureInfo["ExceptionType"] : null,
                TargetMethod = stack.SignatureInfo.ContainsKey("Method") ? stack.SignatureInfo["Method"] : null,
                ProjectId = stack.ProjectId,
                ProjectName = project.Name,
                OrganizationId = stack.OrganizationId,
                OrganizationName = organization.Name,
                TotalOccurrences = stack.TotalOccurrences,
                FirstOccurrence = stack.FirstOccurrence,
                LastOccurrence = stack.LastOccurrence,
                DateFixed = stack.DateFixed,
                IsRegression = stack.IsRegressed,
                IsCritical = stack.OccurrencesAreCritical || stack.Tags != null && stack.Tags.Contains("Critical"),
                FixedInVersion = stack.FixedInVersion
            };
        }
        public override void Process(ErrorPipelineContext ctx) {
            ctx.StackingInfo = ctx.Error.GetStackingInfo(_signatureFactory);
            if (String.IsNullOrEmpty(ctx.Error.ErrorStackId)) {
                if (_stackRepository == null)
                    throw new InvalidOperationException("You must pass a non-null stackRepository parameter to the constructor.");

                Log.Trace().Message("Error did not specify an ErrorStackId.").Write();
                var signature = _signatureFactory.GetSignature(ctx.Error);
                ctx.StackingInfo = ctx.Error.GetStackingInfo();
                // Set Path to be the only thing we stack on for 404 errors
                if (ctx.Error.Is404() && ctx.Error.RequestInfo != null) {
                    Log.Trace().Message("Updating SignatureInfo for 404 error.").Write();
                    signature.SignatureInfo.Clear();
                    signature.SignatureInfo.Add("HttpMethod", ctx.Error.RequestInfo.HttpMethod);
                    signature.SignatureInfo.Add("Path", ctx.Error.RequestInfo.Path);
                    signature.RecalculateHash();
                }

                ctx.StackInfo = _stackRepository.GetErrorStackInfoBySignatureHash(ctx.Error.ProjectId, signature.SignatureHash);
                if (ctx.StackInfo == null) {
                    Log.Trace().Message("Creating new error stack.").Write();
                    ctx.IsNew = true;
                    var stack = new ErrorStack {
                        OrganizationId = ctx.Error.OrganizationId,
                        ProjectId = ctx.Error.ProjectId,
                        SignatureInfo = signature.SignatureInfo,
                        SignatureHash = signature.SignatureHash,
                        Title = ctx.StackingInfo.Message,
                        Tags = ctx.Error.Tags ?? new TagSet(),
                        TotalOccurrences = 1,
                        FirstOccurrence = ctx.Error.OccurrenceDate.UtcDateTime,
                        LastOccurrence = ctx.Error.OccurrenceDate.UtcDateTime
                    };

                    _stackRepository.Add(stack, true);
                    ctx.StackInfo = new ErrorStackInfo {
                        Id = stack.Id,
                        DateFixed = stack.DateFixed,
                        OccurrencesAreCritical = stack.OccurrencesAreCritical,
                        SignatureHash = stack.SignatureHash
                    };

                    // new 404 stack id added, invalidate 404 id cache
                    if (signature.SignatureInfo.ContainsKey("Path"))
                        _stackRepository.InvalidateNotFoundIdsCache(ctx.Error.ProjectId);
                }

                Log.Trace().Message("Updating error's ErrorStackId to: {0}", ctx.StackInfo.Id).Write();
                ctx.Error.ErrorStackId = ctx.StackInfo.Id;
            } else {
                var stack = _stackRepository.GetByIdCached(ctx.Error.ErrorStackId, true);

                // TODO: Update unit tests to work with this check.
                //if (stack == null || stack.ProjectId != error.ProjectId)
                //    throw new InvalidOperationException("Invalid ErrorStackId.");
                if (stack == null)
                    return;

                if (ctx.Error.Tags != null && ctx.Error.Tags.Count > 0) {
                    if(stack.Tags == null)
                        stack.Tags = new TagSet();

                    List<string> newTags = ctx.Error.Tags.Where(t => !stack.Tags.Contains(t)).ToList();
                    if (newTags.Count > 0) {
                        stack.Tags.AddRange(newTags);
                        _stackRepository.Update(stack);
                    }
                }

                ctx.StackInfo = new ErrorStackInfo {
                    Id = stack.Id,
                    DateFixed = stack.DateFixed,
                    OccurrencesAreCritical = stack.OccurrencesAreCritical,
                    SignatureHash = stack.SignatureHash,
                    IsHidden = stack.IsHidden
                };
            }

            // sync the fixed and hidden flags to the error occurrence
            ctx.Error.IsFixed = ctx.StackInfo.DateFixed.HasValue;
            ctx.Error.IsHidden = ctx.StackInfo.IsHidden;
        }