No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TryCatch.cs 2.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System;
  2. namespace Unity.VisualScripting
  3. {
  4. /// <summary>
  5. /// Handles an exception if it occurs.
  6. /// </summary>
  7. [UnitCategory("Control")]
  8. [UnitOrder(17)]
  9. [UnitFooterPorts(ControlOutputs = true)]
  10. public sealed class TryCatch : Unit
  11. {
  12. /// <summary>
  13. /// The entry point for the try-catch block.
  14. /// </summary>
  15. [DoNotSerialize]
  16. [PortLabelHidden]
  17. public ControlInput enter { get; private set; }
  18. /// <summary>
  19. /// The action to attempt.
  20. /// </summary>
  21. [DoNotSerialize]
  22. public ControlOutput @try { get; private set; }
  23. /// <summary>
  24. /// The action to execute if an exception is thrown.
  25. /// </summary>
  26. [DoNotSerialize]
  27. public ControlOutput @catch { get; private set; }
  28. /// <summary>
  29. /// The action to execute afterwards, regardless of whether there was an exception.
  30. /// </summary>
  31. [DoNotSerialize]
  32. public ControlOutput @finally { get; private set; }
  33. /// <summary>
  34. /// The exception that was thrown in the try block.
  35. /// </summary>
  36. [DoNotSerialize]
  37. public ValueOutput exception { get; private set; }
  38. [Serialize]
  39. [Inspectable, UnitHeaderInspectable]
  40. [TypeFilter(typeof(Exception), Matching = TypesMatching.AssignableToAll)]
  41. [TypeSet(TypeSet.SettingsAssembliesTypes)]
  42. public Type exceptionType { get; set; } = typeof(Exception);
  43. public override bool canDefine => exceptionType != null && typeof(Exception).IsAssignableFrom(exceptionType);
  44. protected override void Definition()
  45. {
  46. enter = ControlInput(nameof(enter), Enter);
  47. @try = ControlOutput(nameof(@try));
  48. @catch = ControlOutput(nameof(@catch));
  49. @finally = ControlOutput(nameof(@finally));
  50. exception = ValueOutput(exceptionType, nameof(exception));
  51. Assignment(enter, exception);
  52. Succession(enter, @try);
  53. Succession(enter, @catch);
  54. Succession(enter, @finally);
  55. }
  56. public ControlOutput Enter(Flow flow)
  57. {
  58. if (flow.isCoroutine)
  59. {
  60. throw new NotSupportedException("Coroutines cannot catch exceptions.");
  61. }
  62. try
  63. {
  64. flow.Invoke(@try);
  65. }
  66. catch (Exception ex)
  67. {
  68. if (exceptionType.IsInstanceOfType(ex))
  69. {
  70. flow.SetValue(exception, ex);
  71. flow.Invoke(@catch);
  72. }
  73. else
  74. {
  75. throw;
  76. }
  77. }
  78. finally
  79. {
  80. flow.Invoke(@finally);
  81. }
  82. return null;
  83. }
  84. }
  85. }