Last active
June 20, 2025 07:35
-
-
Save japhib/04d1443ef4ad879e5f822e058c2e4752 to your computer and use it in GitHub Desktop.
How to call a Unity coroutine within a try/catch block
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
yield return current don't take into account inner IEnumerators.
I think this will be better: