From 9bf1ad71b43e41a3dfe645ccf66c6fb6b2e96242 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 21 Nov 2016 22:09:02 -0500 Subject: intercept event handler exceptions (#179) --- .../Framework/InternalExtensions.cs | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/StardewModdingAPI/Framework/InternalExtensions.cs (limited to 'src/StardewModdingAPI/Framework') diff --git a/src/StardewModdingAPI/Framework/InternalExtensions.cs b/src/StardewModdingAPI/Framework/InternalExtensions.cs new file mode 100644 index 00000000..d08d12f3 --- /dev/null +++ b/src/StardewModdingAPI/Framework/InternalExtensions.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace StardewModdingAPI.Framework +{ + /// Provides extension methods for SMAPI's internal use. + internal static class InternalExtensions + { + /********* + ** Public methods + *********/ + /**** + ** IMonitor + ****/ + /// Safely raise an event, and intercept any exceptions thrown by its handlers. + /// Encapsulates monitoring and logging. + /// The event name for error messages. + /// The event handlers. + /// The event sender. + /// The event arguments (or null to pass ). + public static void SafelyRaisePlainEvent(this IMonitor monitor, string name, IEnumerable handlers, object sender = null, EventArgs args = null) + { + if (handlers == null) + return; + + foreach (EventHandler handler in Enumerable.Cast(handlers)) + { + try + { + handler.Invoke(sender, args ?? EventArgs.Empty); + } + catch (Exception ex) + { + monitor.Log($"A mod failed handling the {name} event:\n{ex}", LogLevel.Error); + } + } + } + + /// Safely raise an event, and intercept any exceptions thrown by its handlers. + /// The event argument object type. + /// Encapsulates monitoring and logging. + /// The event name for error messages. + /// The event handlers. + /// The event sender. + /// The event arguments. + public static void SafelyRaiseGenericEvent(this IMonitor monitor, string name, IEnumerable handlers, object sender, TEventArgs args) + { + if (handlers == null) + return; + + foreach (EventHandler handler in Enumerable.Cast>(handlers)) + { + try + { + handler.Invoke(sender, args); + } + catch (Exception ex) + { + monitor.Log($"A mod failed handling the {name} event:\n{ex}", LogLevel.Error); + } + } + } + } +} -- cgit