Warning: An error occured during save.
We recommend that you run RECOVER on the drawing.
Is it possible to provide a definitive reason for this message? There's obviously something in the (ObjectARX) code that triggers this message, and I'm trying to figure it out.
I have one particular custom object that triggers it. I can do a normal COPY on the object, and it works just fine - no error messages and no apparent anomalies on the resulting entities. It is only when I do COPYCLIP that it gives this message. My understanding is that the only difference between COPY and COPYCLIP is that the latter is filing (using a cloning filer?) to another database that is hidden, effectively the clipboard. So why does the cloning filer work OK for COPY, and not for COPYCLIP? The filer returns eOk for filerStatus() at the end of both the dwgInFields() and dwgOutFields() calls, so whatever triggers it is outside of our code.
I am *only* trying to copy that one object, so there isn't another object higher up causing it (at least, there's only one object in the selection set when I hit COPYCLIP). This object references other entities by ID; all but one of them are standard AutoCAD lines, polylines and / or text objects that it owns. One is a reference to an object higher in the owner chain, in that this object refers to object A, A contains a reference to B, and B contains a reference to this object. I've tried *not* filing that reference in case it was a circular dependency issue (by reference I mean standard AcDbObjectIds), but it seems to make no difference.
If anyone could say "It happens because of XYZ or ABC", then at least I'd know more of where to look.
_COPYCLIP uses wblockClone(), whereas _COPY uses deepClone(). In any case, there's no way to guess a specific reason; your best bet is to continue your strategy of removing a little bit at a time until the error goes away.
What I was really hoping was that someone who knew the source code of the ObjectArx libraries could explain it. Somewhere in that source code must be one or more lines of the form
if (this condition occurs)
and I'd like to know what those condition(s) are. According to my object's filers there are no errors - which suggests that the error message is not accurate enough.
If I stop the object from filing anything except to call its base class (this same base class is used in many other objects and doesn't cause the problem - and this object does not exercise any parts of the base class other objects don't also use), and I also block clone nothing but the object itself, I *still* get the error. I'm a little puzzled!
Any other suggestions as to where I might look?
For this particular case, I found the answer finally. We almost always use AcDbObjectId for both owned objects and objects that we are just referring back to (we don't own them). Under the hood, we file them in and out as soft pointers.
We put an error check in during the filing in that read the soft pointer from the stream, but then if it wasn't valid or was null, did not copy it to the target ID variable. The problem was, that meant that the variable being passed in by reference was never being initialised to a known value, relying on the calling code to properly initialise it; the way we normally use it, this is almost never the case. So my object was getting an uninitialised ID at the end of filing. Because the filer *did* read something in correctly, it never thought it had a problem; but the system obviously found later that the ID was invalid and threw the error.
A pity it couldn't have said 'invalid object ID' to make it clearer.
Moral of the story: when filing in object IDs, always ensure yours is initialised properly one way or another!