Search code examples
c#unity-game-engineexceptionassertion

How to prevent Unity from catching and ignoring ALL exceptions


I am making a simple game in Unity. Because the time is limited, I don't write unit tests. Instead, I heavily employ assertions (Debug.Assert) and exceptions to ensure the correctness of my game logic.

However, the mechanism that I rely on to ensure the correctness is completely destroyed by the most frustrating design decision of Unity --- it catches all exceptions and assertions and prints them in the log. Then, it continues executing the game as if nothing has happened.

This choice of Unity makes it completely impossible for the following things:

  1. The debugger breaks the program when an assertion failed or an exception is not handled
  2. I can then debug through the call stack and check the variable values in watch to see what went wrong

Hence my question: How to prevent Unity from doing that?

What I have tried:

In Visual Studio, Debug -> Windows -> Exception Settings, make the debugger to break immediately if an exception is thrown, whether may be handled or not.

However, because Unity itself does not care about (to clarify: probably caught and ignored) some exceptions thrown by itself, whenever I debug my program this way, I will be overwhelmed by exceptions thrown by the Unity engine first. So this unfortunately cannot work.


Solution

  • After some heavy search on the Internet, I have to eventually come to implementing my own assertion function and replace all existing fatal exceptions thrown with this assertion, like @shingo suggested in comment.

    Although this way I lose the type of the exceptions, at least the debugger will stop the game whenever something went wrong.

    public static void MyDebugAssert(bool condition, String msg = "")
    {
        if(!condition)
        {
            Debugger.Break();
            Debugger.Log(0, "Assertion", "Debug Assertion Failed!\n" + msg);
            //ExitProcess(-1);
            Application.Quit(-1);
        }
    }
    

    Nevertheless, this has a major drawback --- All exceptions caused by other mistakes of mine, like NullReferenceException, will still be ignored. These exceptions are usually thrown when I forgot to init something or setup something correctly.

    I would like to investigate further but as I stated in the question, I have limited time to implement this game, so I will just work this way for now.