BeforeDeleteObject Event Handler - Deleting SubObjects

I have an object hierarchy and it's giving me some challenges in my event handlers when deleting objects.

When I try to delete a PARENT object, and it warns me that it will be deleting the child objects, I then receive an error:

CoContextMenu.cpp, 740, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CommandStore.cpp, 403, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MFShellCommands.cpp, 16914, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MCommands.cpp, 317, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MFShellCommands.cpp, 849, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MFShellCommands.cpp, 5129, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MFShellCommands.cpp, 13009, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CoShellFolder.cpp, 3885, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CoShellFolder.cpp, 10123, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
VaultDocumentOperations.cpp, 961, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
VaultDocumentOperations.cpp, 1014, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
ThreadOutCaller.cpp, 67, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
ThreadOutCaller.cpp, 583, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
VaultMethodCallTasks.cpp, 883, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CoVaultMountingDocumentOperations.cpp, 1067, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
DocumentCache.cpp, 8326, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
DocumentCache.cpp, 20002, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
IRPCObjectOperations.generated.cpp, 4847, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
gRPCClient.cpp, 496, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
gRPCClient.cpp, 465, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
gRPCClient.cpp, 98, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
gRPC.generated.cpp, 15143, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
RPCDocumentOperations.cpp, 6548, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MCallInLoop.h, 521, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
RPCDocumentOperationsHelper.cpp, 2789, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
RPCDocumentOperationsHelperPrivate.cpp, 13416, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
RPCObjectTypesHelper.cpp, 10618, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
RPCDocumentOperationsHelper.cpp, 18813, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
RPCDocumentOperationsHelperPrivate.cpp, 17001, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CachedDBSession.cpp, 785, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CachedDBSession.cpp, 942, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CachedDBSession.cpp, 996, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CachedDBSession.cpp, 941, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CachedDBSession.cpp, 1145, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
SQLHelper.cpp, 7171, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
CachedDBSession.cpp, 1143, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MCommand.h, 584, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MCommand.h, 843, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MCommand.h, 801, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
MCommand.h, 583, Error 50000, Level 11, State 1, Procedure -, Line 1, Message: Count mismatch SQL error. [2] (ERROR: 50000, SQLSTATE: 42000) (0x80040E14)
(M-Files 23.4.12528.8 2023-04-27T13:37:47.457Z)

This error occurs if I delete the parent, but not if I first delete all child objects and THEN attempt to delete the parent. What I would like to do is to catch this in an event handler and use MFScriptCancel if the user is deleting the parent object and the parent has children.

I've tried to do this with a "BeforeDeleteObject" event handler looking for the parent object type, checking if the parent has children, and then cancelling execution.

Unfortunately it seems like when you delete a parent and it's children M-Files separately deletes the children first, so it's not possible for me to tell if the parent has children, as by the time it gets to that point the children must have already been deleted. It also doesn't appear to count as a recursive call, as I'm not able to tell that the action deleting the child is not the parent transaction when I try checking the current / parent / master transaction IDs.

Any help with this would be great!

  • Just giving this a bump - hope somebody from the M-Files side can provide some information here?

  • Have you raised this as a support ticket?  When you delete the parent the system should warn you that it's going to delete the children, and then (if you say to continue) delete the children.  If it throws an error then it sounds like something isn't working properly.

    I wouldn't immediately jump to writing script here (for a variety of reasons, including some that you've documented).

  • Hi Craig,

    Not yet - only because I'm doing some slightly odd stuff so I was hoping somebody here had encountered the error.

    The problem that (may) be occurring here is that I have a set of objects in a parent child relationship as follows:

    1. budget
      1. WBS
        1. task

    Using event handlers, whenever a task is updated I update the WBS and budget. I also have to do this whenever a task is deleted or destroyed.

    The problem I run into is when I am trying to delete a WBS, and it then tries to delete the tasks, each task would then try to update the WBS and budget when it's deleted. Obviously this could cause data precedence issues, so instead all I'm trying to do is check when I try to delete a WBS whether it already has children, but even if in the event handler I put in a cancel step right at the beginning if the object being deleted is a WBS, it still chokes out (it actually gets to the step of deleting the children BEFORE it runs the step on deleting the WBS, which makes sense).

    The big problem I have is that I don't seem to be able to identify whether a child is being deleted as part of an activity to also delete the parents, all I want to do is catch this case and then cancel the script with an error stating "you have to delete all tasks before deleting a WBS"... I thought that the current transaction, parent transaction, and master transaction would facilitate this, but they all seem to have matching values.

  • I've not come across this before, but I can see why the above may cause an issue.  If you're using the VAF then you may want to move the processing of this logic to an async handler (i.e. use the event handler to add something to a queue, then use a processor to handle the actual update logic); that way the "delete" should have committed by the time the processor runs, so you can attempt to load the object and handle the exception.

    This does mean that, in the case of deletions, there could be a short (~30s?) delay in updating the calculated value.  That may change the user flow, of course.