Skip to content

Commit 67c96ba

Browse files
committed
Configuration: Strengthen exception reporting
1 parent d7348ce commit 67c96ba

7 files changed

Lines changed: 86 additions & 40 deletions

File tree

LukeBot.Common/Configuration.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,15 @@ public static ConfigurationBase Deserialize(string confString)
7777
);
7878

7979
MethodInfo deserializer = deserializerGeneric.MakeGenericMethod(new Type[] { confType[0] });
80-
return deserializer.Invoke(null, new[] { confString }) as ConfigurationBase;
80+
81+
try
82+
{
83+
return deserializer.Invoke(null, new[] { confString }) as ConfigurationBase;
84+
}
85+
catch (TargetInvocationException e)
86+
{
87+
throw new ConfigurationException("Deserialization failed, deserializer caught an exception", e.InnerException);
88+
}
8189
}
8290
}
8391

@@ -296,7 +304,7 @@ private ConfigurationField AllocateFieldAccessor(object owner, FieldInfo fi, Con
296304
}
297305
catch (TargetInvocationException e)
298306
{
299-
throw e.InnerException;
307+
throw new ConfigurationException("Configuration Field constructor threw an Exception", e.InnerException);
300308
}
301309
}
302310

LukeBot.Common/Exception/ConfigurationException.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ namespace LukeBot.Common
33
public class ConfigurationException: Exception
44
{
55
public ConfigurationException(string fmt, params object[] args)
6-
: base(string.Format(fmt, args)) {}
6+
: base(string.Format(fmt, args))
7+
{}
8+
9+
public ConfigurationException(string msg, System.Exception inner)
10+
: base(msg, inner)
11+
{}
712
}
813
}

LukeBot.Common/Utils.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Net.Sockets;
66
using System.Runtime.InteropServices;
77
using LukeBot.Config;
8+
using LukeBot.Logging;
89

910

1011
namespace LukeBot.Common
@@ -223,6 +224,33 @@ public static List<string> SplitJSONs(string message)
223224
return messages;
224225
}
225226

227+
private static bool PrintAllExceptionsInner(System.Exception e)
228+
{
229+
if (e == null) return false;
230+
231+
if (!PrintAllExceptionsInner(e.InnerException))
232+
{
233+
Logger.Log().Error("Caused by {0}: {1}", e.GetType().ToString(), e.Message);
234+
}
235+
else
236+
{
237+
Logger.Log().Error("...which caused {0}: {1}", e.GetType().ToString(), e.Message);
238+
}
239+
Logger.Log().Trace("Stack trace:{0}\n", e.StackTrace);
240+
return true;
241+
}
242+
243+
/**
244+
* Prints exception chain until InnerException is null
245+
*/
246+
public static void PrintAllExceptions(string errorMsg, System.Exception e)
247+
{
248+
if (e == null) return;
249+
250+
Logger.Log().Error(errorMsg);
251+
PrintAllExceptionsInner(e);
252+
}
253+
226254
// Common Config interactions //
227255

228256
private static Path GetUserModulesPath(string service)

LukeBot.Widget/Alerts.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,24 @@ public AlertInterrupt()
3030
}
3131
}
3232

33+
public class AlertTrigger
34+
{
35+
[ConfigurationListRestrictedField<string>(new[] { "sub", "giftsub", "cheer" })]
36+
private string EventType = "sub";
37+
[ConfigurationListRestrictedField<int>(new[] { 1, 2, 3 })]
38+
private int SubTier = 1;
39+
private int FromMonths = 0;
40+
private int ToMonths = 0;
41+
}
42+
3343
public class Config: Configuration<Config>
3444
{
3545
[ConfigurationListRestrictedField<string>(new[] { "left", "right" })]
36-
private string Alignment;
37-
38-
public Config()
39-
: this("right")
40-
{
41-
}
46+
private string Alignment = "right";
47+
[ConfigurationListRestrictedField<string>(new[] { "simple", "classic" })]
48+
private string Style = "simple";
4249

43-
public Config(string alignment)
44-
{
45-
Alignment = alignment;
46-
}
50+
public Config() {}
4751
}
4852

4953
private void AwaitEventCompletion()

LukeBot.Widget/IWidget.cs

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ private string GetWidgetWSAddress()
8383
return "wss://" + serverAddress + "/widgetws/" + ID;
8484
}
8585

86-
private string GetPrintableWidgetID()
86+
internal string GetPrintableWidgetID()
8787
{
8888
if (Name.Length > 0) return Name;
8989
else return ID;
@@ -214,31 +214,18 @@ protected void SendToWS<T>(T obj)
214214

215215
protected void LoadConfiguration()
216216
{
217-
try
217+
if (Conf.TryGet<string>(mConfigurationPath, out string configStr))
218218
{
219-
if (Conf.TryGet<string>(mConfigurationPath, out string configStr))
220-
{
221-
mConfiguration = ConfigurationFactory.Deserialize(configStr);
222-
}
223-
else
224-
{
225-
mConfiguration = CreateDefaultConfiguration();
226-
}
227-
228-
// Add the UpdateNotifier and afterwards manually trigger the Configuration update
229-
mConfiguration.UpdateNotifier = OnConfigurationUpdate;
230-
OnConfigurationUpdate();
219+
mConfiguration = ConfigurationFactory.Deserialize(configStr);
231220
}
232-
catch (ConfigurationException e)
221+
else
233222
{
234-
Logger.Log().Error("Failed to load {0} Widget's configuration. This might be because it is either old or becuase of some other error.");
235-
Logger.Log().Error("If you're okay with losing the configuration data, try calling below CLI command to recreate it:");
236-
Logger.Log().Error(" widget reload {0} --recreate-config", GetPrintableWidgetID());
237-
Logger.Log().Error("Old configuration will be backed up in config for cross-reference.");
238-
#pragma warning disable CA2200
239-
throw e;
240-
#pragma warning restore CA2200
223+
mConfiguration = CreateDefaultConfiguration();
241224
}
225+
226+
// Add the UpdateNotifier and afterwards manually trigger the Configuration update
227+
mConfiguration.UpdateNotifier = OnConfigurationUpdate;
228+
OnConfigurationUpdate();
242229
}
243230

244231
public void SaveConfiguration()

LukeBot.Widget/WidgetUserModule.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,24 @@ private void LoadWidget(string id)
127127
// Load() can fail, which will leave the Widget in unloaded state.
128128
w.Load();
129129
}
130+
catch (ConfigurationException e)
131+
{
132+
Logger.Log().Error("Failed to load {0} Widget's configuration. This might be because it is either old or becuase of some other error.", w.GetPrintableWidgetID());
133+
Logger.Log().Error("If you're okay with losing the configuration data, try calling below CLI command to recreate it:");
134+
Logger.Log().Error(" widget reload {0} --recreate-config", w.GetPrintableWidgetID());
135+
Logger.Log().Error("Old configuration will be backed up in config for cross-reference.");
136+
Utils.PrintAllExceptions("Widget load failed because of a Configuration error.", e);
137+
}
130138
catch (System.Exception e)
131139
{
140+
string errorMsg;
141+
132142
if (w.Name.Length > 0)
133-
Logger.Log().Error("Failed to load Widget {0} ({1}): {2}", w.Name, w.ID, e.Message);
143+
errorMsg = String.Format("Failed to load Widget {0} ({1}): {2}", w.Name, w.ID, e.Message);
134144
else
135-
Logger.Log().Error("Failed to load Widget {0}: {1}", w.ID, e.Message);
136-
Logger.Log().Trace("Stack trace:\n{0}", e.StackTrace);
145+
errorMsg = String.Format("Failed to load Widget {0}: {1}", w.ID, e.Message);
146+
147+
Utils.PrintAllExceptions(errorMsg, e);
137148
}
138149
}
139150

Tools/LukeBot.Tests/Common/ConfigurationTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,11 @@ public void Configuration_RestrictedDefaults()
447447
Assert.AreEqual("second", conf.restrictedSetToSecond);
448448

449449
// empty or incorrect fields should be default-assigned to first value on the list
450-
Assert.ThrowsException<ConfigurationFieldException>(() => new EmptyRestrictedFieldTestConfiguration());
451-
Assert.ThrowsException<ConfigurationFieldException>(() => new WrongDefaultRestrictedFieldTestConfiguration());
450+
ConfigurationException e = Assert.ThrowsException<ConfigurationException>(() => new EmptyRestrictedFieldTestConfiguration());
451+
Assert.IsInstanceOfType(e.InnerException, typeof(ConfigurationFieldException));
452+
453+
e = Assert.ThrowsException<ConfigurationException>(() => new WrongDefaultRestrictedFieldTestConfiguration());
454+
Assert.IsInstanceOfType(e.InnerException, typeof(ConfigurationFieldException));
452455
}
453456
}
454457
}

0 commit comments

Comments
 (0)