Error Handling Resolution Options

Error Handling Resolution Options

AGGilliam
Collaborator Collaborator
1,862 Views
5 Replies
Message 1 of 6

Error Handling Resolution Options

AGGilliam
Collaborator
Collaborator

I started diving further into error handling and I'm struggling to understand the resolution portion of it. I've made a FailurePreprocessing class that will delete a specified warning but obviously that doesn't work for errors. So I added a bit of code to check whether it was an error and resolve it. The default resolution didn't work for this particular error so I tried setting the resolution to DetachElements (the error was due to modifying an element within a group) which also didn't work. I can't seem to ungroup the group through the FailureProcessingEvent either, which is really all I'm trying to do, the transaction ends up getting rolled back instead. I've read through a few other posts as well as some Building Coder posts on the topic, but none of them provided much past FailuresAccessor.ResolveFailure(failure)

 

So, I guess my question is what can you do within the FailuresPreprocessing class and the FailuresProcessing Event? Can you do any sort of modification to the document to attempt to resolve the error? Or am I stuck with clicking UnGroup through the popup window?

0 Likes
Accepted solutions (1)
1,863 Views
5 Replies
Replies (5)
Message 2 of 6

Sean_Page
Collaborator
Collaborator

Are you setting the result of the processor when you have errors?

 

e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit)
Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 3 of 6

AGGilliam
Collaborator
Collaborator

Yes, I've tried setting the result as ProceedWithCommit but the transaction still ended up being rolled back.

0 Likes
Message 4 of 6

Sean_Page
Collaborator
Collaborator

Can you share your Processor class code so we can see what's going on?

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes
Message 5 of 6

AGGilliam
Collaborator
Collaborator

I just ended up swapping the ProceedWithCommit to Continue because I ran into a situation where it couldn't commit so it started an infinite loop. Not sure if that might be related at this point though.

public class AdBlock : IFailuresPreprocessor
    {
        private readonly FailureDefinitionId blockedFailId;
        private UIApplication _uiapp;
        public AdBlock (FailureDefinitionId failure, UIApplication uiapp = null)
        { 
            blockedFailId = failure;
            _uiapp = uiapp;
        }
        public FailureProcessingResult PreprocessFailures(FailuresAccessor accessor)
        {
            IList<FailureMessageAccessor> failList = accessor.GetFailureMessages();
            foreach (FailureMessageAccessor failure in failList)
            {
                FailureDefinitionId failId = failure.GetFailureDefinitionId();
                Guid failGuid = failId.Guid;
                FailureDefinitionRegistry failReg = Autodesk.Revit.ApplicationServices.Application.GetFailureDefinitionRegistry();
                StringBuilder sb = new StringBuilder();
                Type type = typeof(BuiltInFailures);
                Type[] nested = type.GetNestedTypes(System.Reflection.BindingFlags.Public);
                Dictionary<Guid, Type> dict = new Dictionary<Guid, Type>();
                string className = string.Empty;
                foreach (Type nt in nested)
                {
                    className = nt.FullName.Replace('+', '.');
                    sb.AppendLine(string.Format("#### {0} ####", className));
                    foreach (System.Reflection.PropertyInfo pInfo in nt.GetProperties())
                    {
                        System.Reflection.MethodInfo mInfo = pInfo.GetGetMethod();
                        FailureDefinitionId res = mInfo.Invoke(nt, null) as FailureDefinitionId;
                        Guid resGuid = res.Guid;
                        if (res == null) continue;
                        if (dict.ContainsKey(res.Guid)) continue;
                        dict.Add(res.Guid, nt);
                        FailureDefinitionAccessor acc = failReg.FindFailureDefinition(res);
                        if (acc == null) continue;
                        sb.AppendLine(string.Format("  * {0} <{1}> {2}", acc.GetId().Guid, acc.GetSeverity(), className));
                        sb.AppendLine(string.Format("          {0}", acc.GetDescriptionText()));
                    }
                }
                className = "user-defined";
                sb.AppendLine(string.Format("#### {0} ####", className));
                foreach (FailureDefinitionAccessor _acc in failReg.ListAllFailureDefinitions())
                {
                    Type DefType = null;
                    dict.TryGetValue(_acc.GetId().Guid, out DefType);
                    Guid accGuid = _acc.GetId().Guid;
                    if (DefType != null) continue;  // failure already listed
                    sb.AppendLine(string.Format("  * {0} <{1}> {2}", _acc.GetId().Guid, _acc.GetSeverity(), className));
                    sb.AppendLine(string.Format("          {0}", _acc.GetDescriptionText()));
                }
                if (failId == blockedFailId)
                {
                    if (failure.GetSeverity() == FailureSeverity.Warning)
                        accessor.DeleteWarning(failure);
                    else
                    {
                        _uiapp.Application.FailuresProcessing += new EventHandler<Autodesk.Revit.DB.Events.FailuresProcessingEventArgs>(ResolveErrors);
                        return FailureProcessingResult.Continue;
                    }
                }
            }

            return FailureProcessingResult.Continue;
        }

        public void ResolveErrors(object sender, FailuresProcessingEventArgs args)
        {
            FailuresAccessor fa = args.GetFailuresAccessor();
            List<FailureMessageAccessor> failList = new List<FailureMessageAccessor>();
            failList = fa.GetFailureMessages().ToList();
            foreach (FailureMessageAccessor failure in failList)
            {
                List<ElementId> ids = failure.GetFailingElementIds().ToList();
                foreach (ElementId id in ids)
                {
                    Element e = null;
                    try
                    {
                        Application app = sender as Application;
                        DocumentSet set = app.Documents;
                        DocumentSetIterator dsi = set.ForwardIterator();
                        dsi.MoveNext();
                        Document doc = dsi.Current as Document;
                        e = doc.GetElement(id);
                    }
                    catch (Exception ex)
                    { }
                    if (e is Group)
                    {
                        args.SetProcessingResult(FailureProcessingResult.ProceedWithCommit);
                        failure.SetCurrentResolutionType(FailureResolutionType.DetachElements);
                        (e as Group).UngroupMembers();
                        fa.ResolveFailure(failure);
                    }
                }
            }
            //(sender as UIApplication).Application.FailuresProcessing -= new EventHandler<FailuresProcessingEventArgs>(ResolveErrors);
        }
    }
0 Likes
Message 6 of 6

AGGilliam
Collaborator
Collaborator
Accepted solution

I was originally trying to determine if we can actually edit the document and implement our own resolution methods using the FailuresProcessing Event. The sdk says "Handlers of this event have a limited ability to modify the document and/or failures in it" but doesn't seem to clarify what that means. I finally noticed this description in the FailuresAccessor class in the sdk: "While reading from a document during failure processing is allowed, the only way to modify document during failure resolution is via methods provided by this class." which explains why I can't just call the Ungroup method to resolve my error. 

 

Anyway, hopefully someone finds this info useful. Thanks for your help @Sean_Page 

0 Likes