Disable error with 'Error' severity

Disable error with 'Error' severity

tomerFUNPJ
Enthusiast Enthusiast
4,336 Views
28 Replies
Message 1 of 29

Disable error with 'Error' severity

tomerFUNPJ
Enthusiast
Enthusiast

Hello,

 

I have a specific failure that I want to disable.

I'm able to 'catch' the error (With FailuresProcessing event).

The problem is that I can't find a way to disable / delete the error.

DeleteWarning only works for 'Warning' severity, and my failure is 'Error' severity.

 

Thanks in advance!

0 Likes
Accepted solutions (1)
4,337 Views
28 Replies
Replies (28)
Message 2 of 29

jeremy_tammik
Alumni
Alumni

How do you handle the situation manually in the end user interface? Please note that the Revit API almost always just duplicates or provides access to the standard UI functionality.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 29

tomerFUNPJ
Enthusiast
Enthusiast

I'd click 'Cancel' on the popup message (It's the message that warns that deleting a part will cause other parts to be deleted).

My goal is to not show this error.. I'm cancelling the operation itself by posting another failure message saying "operation was cancelled" but the warning of 'deleting part will cause other part to be deleted' is still shown

0 Likes
Message 4 of 29

jeremy_tammik
Alumni
Alumni

Yes, well if you click cancel, then the operation is aborted, isn't it?

 

I would assume that Revit absolutely refuses to perform this operation, because it would corrupt the entire BIM.

 

In the UI you have to cancel it, and in the API the same.

   

A warning is a warning and is permissible. An error is an error and is forbidden.

   

Or am I misunderstanding?

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 5 of 29

tomerFUNPJ
Enthusiast
Enthusiast
Of course.
Revit doesn't refuse. I can also click "Delete" and it'll delete the part (and the associated parts as well). Nothing will be corrupt.

My goal is to not show this error message from the start. I am eventually not performing the deletion (I'm blocking it with creating my own error using FailuresProcessing as I mentioned before). So I want to prevent from this error to appear in the first place..
0 Likes
Message 6 of 29

jeremy_tammik
Alumni
Alumni

Sorry, I do not understand. If you want to delete the element causing the error, why don't you just delete it? Then, no error will be caused. You can see how lost I am here...

 

However, regardless of whether I understand or not, maybe the previous discussions of the Failure API functionality and usage will help solve the issue?

 

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.32

   

Or previous discussions here in the forum?

 

Or maybe even the warning swallower?

 

https://forums.autodesk.com/t5/revit-api-forum/failure-processing-warnings-swallower-only-for-specif...

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 7 of 29

aignatovich
Advisor
Advisor

Hi guys,

 

@tomerFUNPJ , I think, you could try to either resolve the failure or rollback transaction?

 

If so you could try to delete elements automatically in your failure preprocessor:

 

if (failureAccessor.HasResolutionOfType(FailureResolutionType.DeleteElements))
{
    failureAccessor.SetCurrentResolutionType(FailureResolutionType.DeleteElements);
    failuresAccessor.ResolveFailure(failureAccessor);
}

 

You should return FailureProcessingResult.ProceedWithCommit if you set resolution type.

 

This failure preprocessor solves a bit different task, but I think it could help you:

    public class AutoDetachOrDeleteFailurePreprocessor : IFailuresPreprocessor
    {
        public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
        {
            var preprocessorMessages = failuresAccessor.GetFailureMessages(FailureSeverity.Error)
                .Union(failuresAccessor.GetFailureMessages(FailureSeverity.Warning))
                .Where(x => x.HasResolutionOfType(FailureResolutionType.DeleteElements) || x.HasResolutionOfType(FailureResolutionType.DetachElements))
                .ToList();

            if (preprocessorMessages.Count == 0)
                return FailureProcessingResult.Continue;

            foreach (var failureAccessor in preprocessorMessages)
            {
                failureAccessor.SetCurrentResolutionType(failureAccessor.HasResolutionOfType(FailureResolutionType.DetachElements) ? FailureResolutionType.DetachElements : FailureResolutionType.DeleteElements);

                failuresAccessor.ResolveFailure(failureAccessor);
            }

            return FailureProcessingResult.ProceedWithCommit;
        }
    }

 

If you can't resolve the error with FailureResolutionType.DeleteElements, then you can return FailureProcessingResult.ProceedWithRollBack

 

In such case you have to set:

failureOptions.SetClearAfterRollback(true);

for your transaction.

 

Hope this helps

0 Likes
Message 8 of 29

tomerFUNPJ
Enthusiast
Enthusiast

I'll explain my flow with more details:

- I'm successfully preventing the users from deleting parts that have a specific scheme I made

- No deletion is done whatsoever. Which is good - that was my goal

- Although no deletion is done, the user still get this warning:

 

I want to hide it because it can be confusing to my user. The problem is that - The severity of this message is 'Error' and not warning and therefore I can't use Failure Accessor 'DeleteWarning' method.

So my question is - Is is possible to prevent showing failures of 'Error' severity?

Untitled.png

Thanks

0 Likes
Message 9 of 29

aignatovich
Advisor
Advisor

Failures with "Error" severity could not be "swallowed". They should be resolved using some resolution type (if supported) or by transition rollback. If the transition is rolled back and you don't want to see messages in the UI, you should set clear after rollback transition option

Message 10 of 29

aignatovich
Advisor
Advisor

Transactions of course, not transitions.... T9, sorry

0 Likes
Message 11 of 29

tomerFUNPJ
Enthusiast
Enthusiast
I tried returning ProceedWithCommit but the error still seems to appear 😞
Although I think I'm getting close
0 Likes
Message 12 of 29

tomerFUNPJ
Enthusiast
Enthusiast
But there's nothing to rollback because the transaction (deletion) didn't happen yet. That's what error warns me from.. I'm trying to return ProceedWithCommit / Continue and still no success..
0 Likes
Message 13 of 29

tomerFUNPJ
Enthusiast
Enthusiast

This is my PreprocessFailures

I'm getting in the for loop, and inside my if statement. And of course - returning ProceedWithRollback. The error still appears..

public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
        {
            IList<FailureMessageAccessor> failList = new List<FailureMessageAccessor>();
            failList = failuresAccessor.GetFailureMessages(); // Inside event handler, get all warnings

            foreach (FailureMessageAccessor failure in failList)
            {
                FailureDefinitionId failID = failure.GetFailureDefinitionId();
                if (failID == BuiltInFailures.DPartFailures.DeletingDPartWillDeleteMorePartsError)
                {
                    failure.SetCurrentResolutionType(FailureResolutionType.Default);
                    failuresAccessor.ResolveFailure(failure);
                    failuresAccessor.GetFailureHandlingOptions().SetClearAfterRollback(true);
                    return FailureProcessingResult.ProceedWithRollBack;
                }
            }

            return FailureProcessingResult.Continue;
        }
0 Likes
Message 14 of 29

aignatovich
Advisor
Advisor

From SDK (FailureResolutionType):

Default - Special (reserved) type. It cannot be used as a type when defining a resolution, but can be used as a key to query default resolution from FailureMessage or FailureDefinition.

 

I don't think you have to call "ResolveFailure" if you want to rollback the transaction

I would try to set "clear after rollback" through transaction options before starting the transaction, e.g.:

 

 

var failureOptions = transaction.GetFailureHandlingOptions();
failureOptions.SetClearAfterRollback(true);
...
transaction.SetFailureHandlingOptions(failureOptions);
transaction.Start();

 

 

0 Likes
Message 15 of 29

tomerFUNPJ
Enthusiast
Enthusiast

But I'm not starting any transaction.. 🙂 At any point
This method is triggered by the user - When he tries to delete an element (that's what I want). I'm preventing the user from deleting the element (Raising a different error saying "Operation is cancelled".)
I just don't want to get the error I attached in the picture a few comments above..

0 Likes
Message 16 of 29

aignatovich
Advisor
Advisor

Do you use

Application.RegisterFailuresProcessor

method?

 

I personally would suggest to avoid this...

From SDK:

Replaces Revit's default user interface (if present) with alternative handling for all warnings and errors (including those not generated by your application) for the rest of the Revit session; if your application is not prepared to respond to all warnings and errors, consider use of IFailuresPreprocessor (in your opened Transaction) or the FailuresProcessing event instead of this interface.
 
I think a better idea would be to subscribe to Application.FailuresProcessing event.
 
Then - yes, set "clear after rollback" as you did
0 Likes
Message 17 of 29

tomerFUNPJ
Enthusiast
Enthusiast

I am registered to FailuresProcessing 🙂

uiControlledApplication.ControlledApplication.FailuresProcessing += ControlledApplication_FailuresProcessing;

 And it still shows the error..

0 Likes
Message 18 of 29

tomerFUNPJ
Enthusiast
Enthusiast

I am also using IFailuresPreprocessor:

public class FailuresPreProcessor : IFailuresPreprocessor
    {
        public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
        {
            IList<FailureMessageAccessor> failList = new List<FailureMessageAccessor>();
            failList = failuresAccessor.GetFailureMessages(); // Inside event handler, get all warnings

            foreach (FailureMessageAccessor failure in failList)
            {
                FailureDefinitionId failID = failure.GetFailureDefinitionId();
                if (failID == BuiltInFailures.DPartFailures.DeletingDPartWillDeleteMorePartsError)
                {
                    failure.SetCurrentResolutionType(FailureResolutionType.Others);
                    
                    failuresAccessor.GetFailureHandlingOptions().SetClearAfterRollback(true);
                    failuresAccessor.ResolveFailure(failure);
                    return FailureProcessingResult.ProceedWithRollBack;
                }
            }

            return FailureProcessingResult.Continue;
        }
    }

Thanks so much for trying to help. I appreciate it! 

0 Likes
Message 19 of 29

aignatovich
Advisor
Advisor

I guess you should pick one. Have you tried to remove ResolveFailure and left only

return FailureProcessingResult.ProceedWithRollBack;

?

0 Likes
Message 20 of 29

tomerFUNPJ
Enthusiast
Enthusiast
What do you mean by 'pick one'?

I tried to return ProceedWithRollBack and removing ResolveFailure - didn't help.. 😞
0 Likes