Is there a way to resolve or skip over this failure:

Is there a way to resolve or skip over this failure:

sobon.konrad
Advocate Advocate
1,235 Views
1 Reply
Message 1 of 2

Is there a way to resolve or skip over this failure:

sobon.konrad
Advocate
Advocate

Trying to delete a Reference plane that is probably owned by another user throws up a warning: 

Capture.PNG

Now I am trying to resolve it with a Failure Handing as so: 


        public void FailureProcessing(object sender, FailuresProcessingEventArgs e)
        {
            var failureAccessor = e.GetFailuresAccessor();

            var fmas = failureAccessor.GetFailureMessages();
            if (fmas.Count == 0)
            {
                e.SetProcessingResult(FailureProcessingResult.Continue);
            }
            else
            {
                foreach (var fma in fmas)
                {
                    if (failureAccessor.IsFailureResolutionPermitted(fma))
                    {
                        failureAccessor.ResolveFailure(fma);
                    }
                }
                e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit);
            }
        }

Now that will basically request permission from the user and will display this dialog:

 

Capture1.PNG

That's not ideal, since now I am stuck waiting for their reply. 

Is there a way to just RollBack, skip over that element and move on with the remaining ones? 

I tried this: 

 

public void FailureProcessing(object sender, FailuresProcessingEventArgs e)
        {
            var failureAccessor = e.GetFailuresAccessor();

            var fmas = failureAccessor.GetFailureMessages();
            if (fmas.Count == 0)
            {
                e.SetProcessingResult(FailureProcessingResult.Continue);
            }
            else
            {
                foreach (var fma in fmas)
                {
                    if (failureAccessor.IsFailureResolutionPermitted(fma))
                    {
                        failureAccessor.RollBackPendingTransaction();
                    }
                }
                e.SetProcessingResult(FailureProcessingResult.ProceedWithRollBack);
            }
        }

That doesn't do anything. I just end up in the same spot with the warning bubbling back up to surface. 

Here's my code: 

 

[Transaction(TransactionMode.Manual)]
    public class DeleteReferencePlanes : IExternalCommand
    {
        public void FailureProcessing(object sender, FailuresProcessingEventArgs e)
        {
            var failureAccessor = e.GetFailuresAccessor();

            var fmas = failureAccessor.GetFailureMessages();
            if (fmas.Count == 0)
            {
                e.SetProcessingResult(FailureProcessingResult.Continue);
            }
            else
            {
                foreach (var fma in fmas)
                {
                    if (failureAccessor.IsFailureResolutionPermitted(fma))
                    {
                        failureAccessor.RollBackPendingTransaction();
                    }
                }
                e.SetProcessingResult(FailureProcessingResult.ProceedWithRollBack);
            }
        }

        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            // Get application and document objects
            var uiApp = commandData.Application;
            var doc = uiApp.ActiveUIDocument.Document;

            uiApp.Application.FailuresProcessing += FailureProcessing;

            try
            {
                using (var trans = new Transaction(doc, "DeleteReferencePlanes"))
                {
                    // Delete all unnamed Reference Planes in the project
                    // Create Filter to check for Name
                    var provider = new ParameterValueProvider(new ElementId(BuiltInParameter.DATUM_TEXT));
                    var evaluator = new FilterStringEquals();
                    var rule = new FilterStringRule(provider, evaluator, "", false);
                    var filter = new ElementParameterFilter(rule);

                    var refPlanes = new FilteredElementCollector(doc)
                        .OfClass(typeof(ReferencePlane))
                        .WherePasses(filter)
                        .Cast<ReferencePlane>()
                        .ToList();

                    // display progress form
                    var count = 0;
                    var n = refPlanes.Count;
                    var s = "{0} of " + n + " Reference Planes processed...";
                    const string pfCaption = "Delete Unnamed Reference Planes";
                    using (var pf = new ProgressForm(pfCaption, s, n))
                    {
                        // delete all reference planes
                        // do a final check for validity of objects
                        trans.Start();
                        foreach (var plane in refPlanes)
                        {
                            if (WorksharingUtils.GetCheckoutStatus(doc, plane.Id) == CheckoutStatus.OwnedByOtherUser) continue;
                            if (!plane.IsValidObject) continue;

                            using (var subTrans = new SubTransaction(doc))
                            {
                                subTrans.Start();
                                try
                                {
                                    doc.Delete(plane.Id);
                                    count++;
                                    subTrans.Commit();
                                }
                                catch (Exception)
                                {
                                    subTrans.RollBack();
                                }
                                pf.Increment();
                            }
                        }
                        trans.Commit();
                    }
                    // show a dialog box with some basic stats
                    TaskDialog.Show("Delete Reference Planes", "You have successfully deleted " + count + " unnamed reference planes!");
                    return Result.Succeeded;
                }
            }
            // Catch any Exceptions and display them.
            catch (Autodesk.Revit.Exceptions.OperationCanceledException)
            {
                return Result.Cancelled;
            }
            catch (Exception x)
            {
                message = x.Message;
                return Result.Failed;
            }
        }
    }
0 Likes
1,236 Views
1 Reply
Reply (1)
Message 2 of 2

Anonymous
Not applicable

I would be inclined to throw out all that FailureProcessing jazz. You are just deleting reference planes in one fell swoop. In my mind that is one transaction if any. That means putting the iterate refplanes - delete them try catch loop inside of an outer transaction. You would just bump over the error as it occurs without any rollback. Nothing needs to be rolled back. You could test the error type to keep track of what and how many refplanes were not deleted to bring that information outside for some sort of reporting. If these are ref planes your app is creating, then I would assume the user has ownership and the app could keep track of them by ID to be used later in a cleanup routine.  

0 Likes