- Home /
How to properly catch Unity Assertion failures?
I have a custom mesh generation function. Depending on the data passed to this function, it might generate an Assertion Failure, which is displayed in the unity console:
Assertion failed: Converting invalid MinMaxAABB UnityEngine.Mesh:set_vertices(Vector3[])
The line that generate the assertion failure is:
renderedMesh.vertices = tempvertices;
Now obviously, this means there is a problem with the tempvertices provided to the mesh. I’m NOT looking for an answer on what conditions might generate such an assertion failure.
My question is how do I catch it? (So I can display my OWN message in the unity console.)
I have tried putting it in a try-catch
block, just after setting the [UnityEngine.Assertions.Assert.raiseExceptions][1]
flag (which appears to exist expressly for this purpose) to true, like so, but it had no effect on the output:
UnityEngine.Assertions.Assert.raiseExceptions = true;
try
{
renderedMesh.vertices = tempvertices;
}
catch (UnityEngine.Assertions.AssertionException e)
{
Debug.Log("Problem generating mesh for custom object: " + name + " . Aborting mesh generation.");
renderedMesh.name = "Problem generating mesh";
return;
}
[1]: https://docs.unity3d.com/ScriptReference/Assertions.Assert-raiseExceptions.html
Answer by Bunny83 · Oct 11, 2017 at 05:14 AM
First of all assertions are not exceptions. They are similar but serve a different purpose. An assertion should never ever show up. If it does it's usually an indication that there is something wrong in the code.
Second this assertion seems to be a C++ assert inside the native code of Unity. "UnityEngine.Assertions.Assert" is a quite new class and only belongs to managed code. Also unlike the "normal" C++ assert the managed Assert class is only ment for logging those problems. Unity's Assertions usually are not included in a build. Assets are purely ment for debugging and not for control flow at runtime. Even exceptions aren't ment for that.
If the mesh data is user provided your best solution is to manually do some sanity checks on the vertex data before you pass it to your mesh.
Common problems i could think of would be too large float values (large in the sence of magnitude so +-
) or "NaN" values.
"An assertion should never ever show up." I would have to agree. This is actually why I thought I would be able to catch it somehow.
" If it does it's usually an indication that there is something wrong in the code." Something wrong in the unity code for the mesh.vertices accessor, you mean? Or the code providing the user defined verticies?
I really hate doing code duplication, particularly if both are executed at runtime. Frustrating because it appears SO$$anonymous$$E sanity-checks are being done internally by the mesh class. I'd rather have THOSE checks tell me the mesh is invalid or even (not ideal) just not-work without a console message being displayed. Alas, not even SetVerticies returns a success/failure bool.
Guess I'll implement those checks anyway though, I don't see any other option.
" "UnityEngine.Assertions.Assert" is a quite new class and only belongs to managed code." I don't think I understand what you mean by this. What is "managed code", in this context? Is it only available when explicitly used by a DLL?
Thanks again Bunny!
$$anonymous$$anaged code is .NET / $$anonymous$$ono code. Basically all your scripts is managed code as it runs in a managed environment. However also the UnityEngine.dll is a manged dll even though many things actually have external calls into native code. The Unity engine itself is written in C++ so it's native code. .NET / $$anonymous$$ono is just used as scripting backend.
The managed Assert class is only used on the managed side. Unity itself doesn't use it at all as far as i can tell, especially since the actual engine code is not managed code.
Here are two great sources about "when to use exceptions and when not": SE question, blog post of Herb Sutter.
It's generally best practise to verify your data yourself, especially when it comes from an external source. Just relying on error handling of some third party API is never a good idea since you don't know how it might behave unless it's documented. Those are the things which leave an application open for injection attacks (like sql injection, buffer overflow, ...).
Yes, an assertion would actually indicate a program$$anonymous$$g error inside the Unity code itself. However since we all are just humans it's always possible that a programmer used an assertion to just assert that user data is correct, which is the wrong usage for assertions. As a programmer you place an assert at a point where you know, for sure that a variable has a certain value / state. This is just to enforce that a certain contract is not violated due to refactoring or other code changes. Assertions can't be caught as they usually either just output an error log or just halt the whole application.
Great info, good point on attacks! As expected checking the values myself first, resolved the issue.
foreach (Vector3 v in tempvertices)
{
if (float.IsNaN(v.x) || float.IsInfinity(v.x))// to do: also check y, z
{
Debug.Log("Problem generating mesh for object: " + name + " . Aborting mesh generation");
rendered$$anonymous$$esh.name = "Problem generating mesh";
return;
}
}
rendered$$anonymous$$esh.vertices = tempvertices;
Your answer
Follow this Question
Related Questions
C# try catch block doesn't work for iOS? 2 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers