summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-06-01 21:40:17 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-06-01 21:40:17 -0400
commita2523696fd539621351c178f6ff57ade19dd3e34 (patch)
tree1e7c5dccc3b3ed9523807927a7deff6b57ea8d0d /src/SMAPI/Framework
parent07bbfea7dd9dac5bbacf8bfc3c35d3f65ec71b75 (diff)
downloadSMAPI-a2523696fd539621351c178f6ff57ade19dd3e34.tar.gz
SMAPI-a2523696fd539621351c178f6ff57ade19dd3e34.tar.bz2
SMAPI-a2523696fd539621351c178f6ff57ade19dd3e34.zip
fix issue where a mod crashing in CanEdit/CanLoad could cause an abort-retry loop
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs59
1 files changed, 55 insertions, 4 deletions
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index caa5b538..15d39a5c 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -11,7 +11,6 @@ using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Framework.Utilities;
using StardewModdingAPI.Metadata;
using StardewValley;
-using xTile;
namespace StardewModdingAPI.Framework
{
@@ -179,12 +178,36 @@ namespace StardewModdingAPI.Framework
{
// check loaders
MethodInfo canLoadGeneric = canLoad.MakeGenericMethod(asset.DataType);
- if (loaders.Any(loader => (bool)canLoadGeneric.Invoke(loader, new object[] { asset })))
- return true;
+ foreach (IAssetLoader loader in loaders)
+ {
+ try
+ {
+ if ((bool)canLoadGeneric.Invoke(loader, new object[] { asset }))
+ return true;
+ }
+ catch (Exception ex)
+ {
+ this.GetModFor(loader).LogAsMod($"Mod failed when checking whether it could load asset '{asset.AssetName}'. Error details:\n{ex.GetLogSummary()}", LogLevel.Error);
+ }
+ }
// check editors
MethodInfo canEditGeneric = canEdit.MakeGenericMethod(asset.DataType);
- return editors.Any(editor => (bool)canEditGeneric.Invoke(editor, new object[] { asset }));
+ foreach (IAssetEditor editor in editors)
+ {
+ try
+ {
+ if ((bool)canEditGeneric.Invoke(editor, new object[] { asset }))
+ return true;
+ }
+ catch (Exception ex)
+ {
+ this.GetModFor(editor).LogAsMod($"Mod failed when checking whether it could edit asset '{asset.AssetName}'. Error details:\n{ex.GetLogSummary()}", LogLevel.Error);
+ }
+ }
+
+ // asset not affected by a loader or editor
+ return false;
});
}
@@ -259,5 +282,33 @@ namespace StardewModdingAPI.Framework
this.ContentManagers.Remove(contentManager);
}
+
+ /// <summary>Get the mod which registered an asset loader.</summary>
+ /// <param name="loader">The asset loader.</param>
+ /// <exception cref="KeyNotFoundException">The given loader couldn't be matched to a mod.</exception>
+ private IModMetadata GetModFor(IAssetLoader loader)
+ {
+ foreach (var pair in this.Loaders)
+ {
+ if (pair.Value.Contains(loader))
+ return pair.Key;
+ }
+
+ throw new KeyNotFoundException("This loader isn't associated with a known mod.");
+ }
+
+ /// <summary>Get the mod which registered an asset editor.</summary>
+ /// <param name="editor">The asset editor.</param>
+ /// <exception cref="KeyNotFoundException">The given editor couldn't be matched to a mod.</exception>
+ private IModMetadata GetModFor(IAssetEditor editor)
+ {
+ foreach (var pair in this.Editors)
+ {
+ if (pair.Value.Contains(editor))
+ return pair.Key;
+ }
+
+ throw new KeyNotFoundException("This editor isn't associated with a known mod.");
+ }
}
}