diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-11-21 22:09:02 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-11-21 22:09:02 -0500 |
commit | 9bf1ad71b43e41a3dfe645ccf66c6fb6b2e96242 (patch) | |
tree | 689b753b22702c1c3eb8c5fc2ccc4a068a581294 /src/StardewModdingAPI/Framework/InternalExtensions.cs | |
parent | 1a5eb12cc6877da6dd95bcae8814bc5d3fb87a9b (diff) | |
download | SMAPI-9bf1ad71b43e41a3dfe645ccf66c6fb6b2e96242.tar.gz SMAPI-9bf1ad71b43e41a3dfe645ccf66c6fb6b2e96242.tar.bz2 SMAPI-9bf1ad71b43e41a3dfe645ccf66c6fb6b2e96242.zip |
intercept event handler exceptions (#179)
Diffstat (limited to 'src/StardewModdingAPI/Framework/InternalExtensions.cs')
-rw-r--r-- | src/StardewModdingAPI/Framework/InternalExtensions.cs | 65 |
1 files changed, 65 insertions, 0 deletions
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 +{ + /// <summary>Provides extension methods for SMAPI's internal use.</summary> + internal static class InternalExtensions + { + /********* + ** Public methods + *********/ + /**** + ** IMonitor + ****/ + /// <summary>Safely raise an <see cref="EventHandler"/> event, and intercept any exceptions thrown by its handlers.</summary> + /// <param name="monitor">Encapsulates monitoring and logging.</param> + /// <param name="name">The event name for error messages.</param> + /// <param name="handlers">The event handlers.</param> + /// <param name="sender">The event sender.</param> + /// <param name="args">The event arguments (or <c>null</c> to pass <see cref="EventArgs.Empty"/>).</param> + public static void SafelyRaisePlainEvent(this IMonitor monitor, string name, IEnumerable<Delegate> handlers, object sender = null, EventArgs args = null) + { + if (handlers == null) + return; + + foreach (EventHandler handler in Enumerable.Cast<EventHandler>(handlers)) + { + try + { + handler.Invoke(sender, args ?? EventArgs.Empty); + } + catch (Exception ex) + { + monitor.Log($"A mod failed handling the {name} event:\n{ex}", LogLevel.Error); + } + } + } + + /// <summary>Safely raise an <see cref="EventHandler{TEventArgs}"/> event, and intercept any exceptions thrown by its handlers.</summary> + /// <typeparam name="TEventArgs">The event argument object type.</typeparam> + /// <param name="monitor">Encapsulates monitoring and logging.</param> + /// <param name="name">The event name for error messages.</param> + /// <param name="handlers">The event handlers.</param> + /// <param name="sender">The event sender.</param> + /// <param name="args">The event arguments.</param> + public static void SafelyRaiseGenericEvent<TEventArgs>(this IMonitor monitor, string name, IEnumerable<Delegate> handlers, object sender, TEventArgs args) + { + if (handlers == null) + return; + + foreach (EventHandler<TEventArgs> handler in Enumerable.Cast<EventHandler<TEventArgs>>(handlers)) + { + try + { + handler.Invoke(sender, args); + } + catch (Exception ex) + { + monitor.Log($"A mod failed handling the {name} event:\n{ex}", LogLevel.Error); + } + } + } + } +} |