diff --git a/Editor/API/BuildContext.cs b/Editor/API/BuildContext.cs index b77e70f..69bc055 100644 --- a/Editor/API/BuildContext.cs +++ b/Editor/API/BuildContext.cs @@ -312,10 +312,18 @@ public void DeactivateExtensionContext(Type t) { var ctx = _activeExtensions[t]; Profiler.BeginSample("NDMF Deactivate: " + t); + + using var scope = ErrorReport.WithContext(ctx); try { ctx.OnDeactivate(this); } + catch (Exception e) + { + // ensure we report the exception while the error report context is set + ErrorReport.ReportException(e); + return; + } finally { Profiler.EndSample(); @@ -405,10 +413,18 @@ public IExtensionContext ActivateExtensionContext(Type ty) if (!_activeExtensions.ContainsKey(ty)) { Profiler.BeginSample("NDMF Activate: " + ty); + + using var scope = ErrorReport.WithContext(ctx); try { ctx.OnActivate(this); } + catch (Exception e) + { + // ensure we report the exception while the error report context is set + ErrorReport.ReportException(e); + return null; + } finally { Profiler.EndSample(); diff --git a/Editor/API/IExtensionContext.cs b/Editor/API/IExtensionContext.cs index 190c3ac..cbb9395 100644 --- a/Editor/API/IExtensionContext.cs +++ b/Editor/API/IExtensionContext.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -20,6 +22,12 @@ public interface IExtensionContext /// /// void OnDeactivate(BuildContext context); + + /// + /// Return the plugin owning this extension context. Implementing this API is optional for backwards + /// compatibility, but is encouraged as it will provide better error messaging. + /// + PluginBase? Owner => null; } internal static class ExtensionContextUtil diff --git a/Editor/ErrorReporting/ErrorReport.cs b/Editor/ErrorReporting/ErrorReport.cs index 7a94179..94863f1 100644 --- a/Editor/ErrorReporting/ErrorReport.cs +++ b/Editor/ErrorReporting/ErrorReport.cs @@ -308,6 +308,15 @@ internal IDisposable WithContext(PluginBase thePlugin) CurrentContext.Plugin = thePlugin; return scope; } + + internal IDisposable WithContext(IExtensionContext theExtension) + { + var scope = new RestoreContextScope(this); + + if (theExtension.Owner != null) CurrentContext.Plugin = theExtension.Owner; + + return scope; + } internal IDisposable WithContextPassName(string name) {