From 600ef562861fe306390b78ee8f08036f0872e92c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 1 Jul 2017 21:31:21 -0400 Subject: improve error handling when mods set invalid asset value (#255) --- src/StardewModdingAPI/Framework/SContentManager.cs | 30 +++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'src/StardewModdingAPI') diff --git a/src/StardewModdingAPI/Framework/SContentManager.cs b/src/StardewModdingAPI/Framework/SContentManager.cs index 1ee1eae6..53afb729 100644 --- a/src/StardewModdingAPI/Framework/SContentManager.cs +++ b/src/StardewModdingAPI/Framework/SContentManager.cs @@ -219,31 +219,47 @@ namespace StardewModdingAPI.Framework // get metadata IAssetInfo info = new AssetInfo(locale, normalisedKey, typeof(T), this.NormaliseAssetName); - // load asset - T asset = getData(); // edit asset - IAssetData data = new AssetDataForObject(info.Locale, info.AssetName, asset, this.NormaliseAssetName); + IAssetData data = this.GetAssetData(info, getData()); foreach (var entry in this.GetAssetEditors()) { + // check for match IModMetadata mod = entry.Mod; IAssetEditor editor = entry.Editor; - if (!editor.CanEdit(info)) continue; + // try edit this.Monitor.Log($"{mod.DisplayName} intercepted {info.AssetName}.", LogLevel.Trace); + object prevAsset = data.Data; editor.Edit(data); + + // validate edit if (data.Data == null) - throw new InvalidOperationException($"{mod.DisplayName} incorrectly set asset '{normalisedKey}' to a null value."); - if (!(data.Data is T)) - throw new InvalidOperationException($"{mod.DisplayName} incorrectly set asset '{normalisedKey}' to incompatible type '{data.Data.GetType()}', expected '{typeof(T)}'."); + { + data = this.GetAssetData(info, prevAsset); + this.Monitor.Log($"{mod.DisplayName} incorrectly set asset '{normalisedKey}' to a null value; ignoring override.", LogLevel.Warn); + } + else if (!(data.Data is T)) + { + data = this.GetAssetData(info, prevAsset); + this.Monitor.Log($"{mod.DisplayName} incorrectly set asset '{normalisedKey}' to incompatible type '{data.Data.GetType()}', expected '{typeof(T)}'; ignoring override.", LogLevel.Warn); + } } // return result return (T)data.Data; } + /// Get an asset edit helper. + /// The asset info. + /// The loaded asset data. + private IAssetData GetAssetData(IAssetInfo info, object asset) + { + return new AssetDataForObject(info.Locale, info.AssetName, asset, this.NormaliseAssetName); + } + /// Get all registered asset editors. private IEnumerable<(IModMetadata Mod, IAssetEditor Editor)> GetAssetEditors() { -- cgit