A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections.Generic; 3using UnityEngine; 4 5namespace Unity.VisualScripting 6{ 7 public static class GraphsExceptionUtility 8 { 9 // Note: Checking hasDebugData here instead of enableDebug, 10 // because we always want exceptions to register, even if 11 // background debug is disabled. 12 13 private const string handledKey = "Bolt.Core.Handled"; 14 15 public static Exception GetException(this IGraphElementWithDebugData element, GraphPointer pointer) 16 { 17 if (!pointer.hasDebugData) 18 { 19 return null; 20 } 21 22 var debugData = pointer.GetElementDebugData<IGraphElementDebugData>(element); 23 24 return debugData.runtimeException; 25 } 26 27 public static void SetException(this IGraphElementWithDebugData element, GraphPointer pointer, Exception ex) 28 { 29 if (!pointer.hasDebugData) 30 { 31 return; 32 } 33 34 var debugData = pointer.GetElementDebugData<IGraphElementDebugData>(element); 35 36 debugData.runtimeException = ex; 37 } 38 39 public static void HandleException(this IGraphElementWithDebugData element, GraphPointer pointer, Exception ex) 40 { 41 Ensure.That(nameof(ex)).IsNotNull(ex); 42 43 if (pointer == null) 44 { 45 Debug.LogError("Caught exception with null graph pointer (flow was likely disposed):\n" + ex); 46 return; 47 } 48 49 var reference = pointer.AsReference(); 50 51 if (!ex.HandledIn(reference)) 52 { 53 element.SetException(pointer, ex); 54 } 55 56 while (reference.isChild) 57 { 58 var parentElement = reference.parentElement; 59 reference = reference.ParentReference(true); 60 61 if (parentElement is IGraphElementWithDebugData debuggableParentElement) 62 { 63 if (!ex.HandledIn(reference)) 64 { 65 debuggableParentElement.SetException(reference, ex); 66 } 67 } 68 } 69 } 70 71 private static bool HandledIn(this Exception ex, GraphReference reference) 72 { 73 Ensure.That(nameof(ex)).IsNotNull(ex); 74 75 if (!ex.Data.Contains(handledKey)) 76 { 77 ex.Data.Add(handledKey, new HashSet<GraphReference>()); 78 } 79 80 var handled = (HashSet<GraphReference>)ex.Data[handledKey]; 81 82 if (handled.Contains(reference)) 83 { 84 return true; 85 } 86 else 87 { 88 handled.Add(reference); 89 return false; 90 } 91 } 92 } 93}