Have you ever ran into the ExitGUIException in Unity and wondered what exactly it is?

I did a deep dive into investigating what it is and what should be done when encountering it, and here are my findings.

What is the ExitGUIException?

Unity has a class called GUIUtility that contains the method ExitGUI which looks like this:

public static void ExitGUI()
{
	GUIUtility.guiIsExiting = true;
	throw new ExitGUIException();
}

Unity’s documentation on GUIUtility.ExitGUI states the following:

Use GUIUtility.ExitGUI in situations – – such as when a change in some value might change what controls are displayed next. Using this method can prevent errors such as ArgumentException: Getting control 0’s position in a group with only 0 controls when doing Repaint.

So ExitGUIException is something that Unity intentionally throws in its internal code whenever it wants to exit out of GUI drawing code in the middle of it.
This usually happens when the user interacts with the GUI in some way that changes its contents, like clicks a button.

Unity’s IMGUI system will internally handle this exception without any errors appearing in the user’s console, as long as you don’t prevent this by catching it yourself.

How To Properly Handle ExitGUIIException?

Here is how Unity’s Inspector Window handles the ExitGUIException:

try
{
    editor.OnInspectorGUI();
}

catch (Exception exception)
{
    if (GUIUtility.ShouldRethrowException(exception))
    {
        throw;
    }
    Debug.LogException(exception);
}

And here is what the referenced GUIUtility.ShouldRethrowException looks like:

internal static bool ShouldRethrowException(Exception exception)
{
	return GUIUtility.IsExitGUIException(exception);
}

internal static bool IsExitGUIException(Exception exception)
{
	while (exception is TargetInvocationException && exception.InnerException != null)
	{
		exception = exception.InnerException;
	}
	return exception is ExitGUIException;
}

You should do the same thing in your code. Whenever you have OnGUI logic inside a try-catch statement, you should determine if the caught exception is an ExitGUIException, and if it is, rethrow it.

Replicating ShouldRethrowException

Unfortunately for some reason Unity has decided to make GUIUtility.ShouldRethrowException into an internal method, so you will have to replicate the method in your own code before you can use it.

To do so you can add this code into your project inside a file called “ExitGUIUtility.cs”:

using System;
using System.Reflection;
using UnityEngine;

public static class ExitGUIUtility
{
	public static bool ShouldRethrowException(Exception exception)
	{
		return IsExitGUIException(exception);
	}

	public static bool IsExitGUIException(Exception exception)
	{
		while (exception is TargetInvocationException && exception.InnerException != null)
		{
			exception = exception.InnerException;
		}
		return exception is ExitGUIException;
	}
}

You can then use it in your code like this:

try
{
	// Replace this line with your own OnGUI code.
	EditorGUILayout.PropertyField(serializedProperty, label);
}
catch(Exception e)
{
	if(ExitGUIUtility.ShouldRethrowException(e))
	{
		throw;
	}
	Debug.LogException(e);
}