Skip to content

Commit c3f3f66

Browse files
committed
Changed to output more debugging information when coroutines throw exceptions
1 parent 4fee72d commit c3f3f66

File tree

1 file changed

+72
-2
lines changed

1 file changed

+72
-2
lines changed

UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/IEnumeratorAwaitExtensions.cs

+72-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Reflection;
46
using System.Runtime.CompilerServices;
7+
using System.Text;
58
using System.Threading;
6-
using System.Threading.Tasks;
79
using UnityEngine;
810
using UnityAsyncAwaitUtil;
911

@@ -255,7 +257,23 @@ public IEnumerator Run()
255257
}
256258
catch (Exception e)
257259
{
258-
_awaiter.Complete(default(T), e);
260+
// The IEnumerators we have in the process stack do not tell us the
261+
// actual names of the coroutine methods but it does tell us the objects
262+
// that the IEnumerators are associated with, so we can at least try
263+
// adding that to the exception output
264+
var objectTrace = GenerateObjectTrace(_processStack);
265+
266+
if (objectTrace.Any())
267+
{
268+
_awaiter.Complete(
269+
default(T), new Exception(
270+
GenerateObjectTraceMessage(objectTrace), e));
271+
}
272+
else
273+
{
274+
_awaiter.Complete(default(T), e);
275+
}
276+
259277
yield break;
260278
}
261279

@@ -285,6 +303,58 @@ public IEnumerator Run()
285303
}
286304
}
287305
}
306+
307+
string GenerateObjectTraceMessage(List<Type> objTrace)
308+
{
309+
var result = new StringBuilder();
310+
311+
foreach (var objType in objTrace)
312+
{
313+
if (result.Length != 0)
314+
{
315+
result.Append(" -> ");
316+
}
317+
318+
result.Append(objType.ToString());
319+
}
320+
321+
result.AppendLine();
322+
return "Unity Coroutine Object Trace: " + result.ToString();
323+
}
324+
325+
static List<Type> GenerateObjectTrace(IEnumerable<IEnumerator> enumerators)
326+
{
327+
var objTrace = new List<Type>();
328+
329+
foreach (var enumerator in enumerators)
330+
{
331+
// NOTE: This only works with scripting engine 4.6
332+
// And could easily stop working with unity updates
333+
var field = enumerator.GetType().GetField("$this", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
334+
335+
if (field == null)
336+
{
337+
continue;
338+
}
339+
340+
var obj = field.GetValue(enumerator);
341+
342+
if (obj == null)
343+
{
344+
continue;
345+
}
346+
347+
var objType = obj.GetType();
348+
349+
if (!objTrace.Any() || objType != objTrace.Last())
350+
{
351+
objTrace.Add(objType);
352+
}
353+
}
354+
355+
objTrace.Reverse();
356+
return objTrace;
357+
}
288358
}
289359

290360
static class InstructionWrappers

0 commit comments

Comments
 (0)