Skip to content

Instantly share code, notes, and snippets.

@japhib
Last active June 20, 2025 07:35
Show Gist options
  • Select an option

  • Save japhib/04d1443ef4ad879e5f822e058c2e4752 to your computer and use it in GitHub Desktop.

Select an option

Save japhib/04d1443ef4ad879e5f822e058c2e4752 to your computer and use it in GitHub Desktop.
How to call a Unity coroutine within a try/catch block
using UnityEngine;
using System.Collections;
// Adapted from https://jacksondunstan.com/articles/3718
public static class CoroutineUtils
{
// Calls a coroutine but if there's an error in that coroutine, it'll log the error & return
// instead of just killing the caller.
//
// Call it like this:
//
// yield return CoroutineUtils.Try(MyCoroutine());
//
public static IEnumerator Try(IEnumerator enumerator)
{
while (true)
{
object current;
try
{
if (enumerator.MoveNext() == false)
{
break;
}
current = enumerator.Current;
}
catch (Exception ex)
{
Debug.LogError(ex);
yield break;
}
yield return current;
}
}
// Use this function if you want to start a coroutine and add your own error handling behavior.
//
// For example:
//
// CoroutineUtils.StartThrowingCoroutine(
// this,
// MyCoroutine(),
// (ex) => {
// if (ex == null)
// Debug.Log("coroutine completed successfully!");
// else
// Debug.Log("Houson, we have a problem: " + ex);
// }
// );
//
public static Coroutine StartThrowingCoroutine(
MonoBehaviour monoBehaviour,
IEnumerator enumerator,
Action<Exception> done)
{
return monoBehaviour.StartCoroutine(RunThrowingIterator(enumerator, done));
}
public static IEnumerator RunThrowingIterator(
IEnumerator enumerator,
Action<Exception> done)
{
while (true)
{
object current;
try
{
if (enumerator.MoveNext() == false)
{
break;
}
current = enumerator.Current;
}
catch (Exception ex)
{
Debug.LogError(ex);
done?.Invoke(ex);
yield break;
}
yield return current;
}
done?.Invoke(null);
}
}
@xewelus
Copy link

xewelus commented Jun 21, 2024

yield return current don't take into account inner IEnumerators.
I think this will be better:

		public static IEnumerator Try(IEnumerator enumerator, Action<Exception> onError)
		{
			while (true)
			{
				object current;
				try
				{
					if (!enumerator.MoveNext())
					{
						break;
					}
					current = enumerator.Current;
				}
				catch (Exception ex)
				{
					onError(ex);
					yield break;
				}

				if (current is IEnumerator e)
				{
					Exception error = null;
					yield return Try(e, ex => error = ex);
					if (error != null)
					{
						onError(error);
						yield break;
					}
				}
				else
				{
					yield return current;
				}
			}
		}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment