1
votes

The second half of the code in one of my methods is not running. Unity logs main thread exceptions to the console by default. Even though my function is running on the main thread, I don't see any error logs in console. This makes finding bugs and fixing the code really really cumbersome.

Here is my method simplified:

    private void DoInitialize() {
        LogWarn($"HERE 1.5 item {i}"); // this prints
        LogWarn($"THIS SHIT {i.shardPrice.amount}"); // this causes a null pointer exception
        LogWarn($"HERE 1.6 item {i}"); // this doesn't print
    }

I attached the debugger and stepped through code until I found the line that is causing the issue. Commenting out the line will cause the program to run correctly. Upon inspection it turns out I have a null pointer exception in that line.

How do I know the code is running on the main thread? I print the Thread.CurrentThread.ManagedThreadId.ToString() before the faulty line and in Start() callbacks and make sure the id is the same.

Here is the stack trace of the thread just before it goes to some random place I don't have the symbols for. My only explanation for this is that Firebase methods at the bottom of the stack catch the exception and don't let it propagate to Unity. enter image description here

Here are my questions:

  1. Am I missing something in my diagnosis?
  2. How can I confirm Firebase actually catches the exceptions? The SDK code is not on github so I can't take a look at the code. Can someone from the Firebase team verify this?
1
depends ... how is DoInitialize executed? Could you convert your snippet into a minimal reproducible Example? - derHugo
Thanks for the reply @derHugo. I found the reason for this. Seems to be by design since Firebase uses tasks. Read my reply below. - hk1ll3r

1 Answers

1
votes

I realized that since firebase uses C# Tasks, it is expected that the exceptions are caught. I wrote a helper method to print task exceptions to console. You can use it for tasks that you expect to succeed (just like normal Unity code).

    public static class TaskExts {
        public static void LogExceptionIfFaulted(this Task task) {
            task.ContinueWithOnMainThread(t => {
                if (t.IsFaulted) {
                    Debug.LogException(t.Exception.Flatten().InnerException);
                }
            });
        }
    }

usage

    FirebaseRemoteConfig.FetchAsync(TimeSpan.Zero).ContinueWithOnMainThread(task => {
        // custom code which may throw exceptions
    }).LogExceptionIfFaulted();