Skip to content

Commit ad1691d

Browse files
committed
Exceptions are now forwarded to the JoinLeaveLog channel (now renamed to GuildLogging; see the example config)
1 parent cb467d9 commit ad1691d

File tree

6 files changed

+68
-24
lines changed

6 files changed

+68
-24
lines changed

example.volte.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
//same as above but for failures
2020
"log_all_commands": true,
2121
//whether or not to log all commands to the bot's console; enabled by default
22-
"join_leave_log": {
23-
//send a log of the bot's joins/leaves to a channel within a certain guild
22+
"guild_logging": {
23+
//send a log of the bot's guild joins/leaves, as well as any exceptions that occur
2424
"enabled": false,
2525
"guild_id": 0,
2626
"channel_id": 0

src/Commands/Modules/Utility/InfoCommands.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Diagnostics;
1+
using System;
2+
using System.Diagnostics;
23
using System.Linq;
34
using System.Threading.Tasks;
45
using Discord.WebSocket;

src/Core/Config.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static bool CreateIfNotExists()
3131
SuccessEmbedColor = 0x7000FB,
3232
ErrorEmbedColor = 0xFF0000,
3333
LogAllCommands = true,
34-
JoinLeaveLog = new JoinLeaveLog(),
34+
GuildLogging = new GuildLogging(),
3535
BlacklistedGuildOwners = new ulong[] { },
3636
EnabledFeatures = new EnabledFeatures()
3737
};
@@ -90,7 +90,7 @@ public static bool Reload(IServiceProvider provider)
9090

9191
public static bool LogAllCommands => _configuration.LogAllCommands;
9292

93-
public static JoinLeaveLog JoinLeaveLog => _configuration.JoinLeaveLog;
93+
public static GuildLogging GuildLogging => _configuration.GuildLogging;
9494

9595
public static IEnumerable<ulong> BlacklistedOwners => _configuration.BlacklistedGuildOwners;
9696

@@ -126,8 +126,8 @@ private struct BotConfig
126126
[JsonProperty("log_all_commands")]
127127
public bool LogAllCommands { get; internal set; }
128128

129-
[JsonProperty("join_leave_log")]
130-
public JoinLeaveLog JoinLeaveLog { get; internal set; }
129+
[JsonProperty("guild_logging")]
130+
public GuildLogging GuildLogging { get; internal set; }
131131

132132
[JsonProperty("blacklisted_guild_owners")]
133133
public ulong[] BlacklistedGuildOwners { get; internal set; }

src/Core/Models/BotConfig/JoinLeaveLog.cs src/Core/Models/BotConfig/GuildLogging.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace Volte.Core.Models.BotConfig
44
{
5-
public sealed class JoinLeaveLog
5+
public sealed class GuildLogging
66
{
7-
internal JoinLeaveLog()
7+
internal GuildLogging()
88
{
99
Enabled = false;
1010
GuildId = ulong.MinValue;

src/Services/GuildService.cs

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using System;
21
using System.Linq;
2+
using System.Net;
33
using System.Text;
44
using System.Threading.Tasks;
55
using Discord;
@@ -48,36 +48,36 @@ public async Task OnJoinAsync(JoinedGuildEventArgs args)
4848
.ToString())
4949
.AddField("Support Server", "[Join my support Discord here](https://discord.gg/H8bcFr2)");
5050

51-
_logger.Error(LogSource.Volte,
51+
_logger.Debug(LogSource.Volte,
5252
"Attempting to send the guild owner the introduction message.");
5353
try
5454
{
5555
await embed.SendToAsync(args.Guild.Owner);
5656
_logger.Error(LogSource.Volte,
5757
"Sent the guild owner the introduction message.");
5858
}
59-
catch (HttpException ex) when (ex.DiscordCode is 50007)
59+
catch (HttpException ex) when (ex.HttpCode is HttpStatusCode.Forbidden)
6060
{
6161
var c = args.Guild.TextChannels.OrderByDescending(x => x.Position).FirstOrDefault();
6262
_logger.Error(LogSource.Volte,
6363
"Could not DM the guild owner; sending to the upper-most channel instead.");
6464
if (c != null) await embed.SendToAsync(c);
6565
}
6666

67-
if (!Config.JoinLeaveLog.Enabled) return;
68-
var joinLeave = Config.JoinLeaveLog;
69-
if (joinLeave.GuildId is 0 || joinLeave.ChannelId is 0)
67+
if (!Config.GuildLogging.Enabled) return;
68+
var guildLogging = Config.GuildLogging;
69+
if (guildLogging.GuildId is 0 || guildLogging.ChannelId is 0)
7070
{
7171
_logger.Error(LogSource.Volte,
72-
"Invalid value set for the GuildId or ChannelId in the JoinLeaveLog config option. " +
73-
"To fix, set Enabled to false, or correctly fill in your options.");
72+
"Invalid value set for the guild_id or channel_id in the guild_logging config section. " +
73+
"To fix, set enabled to false, or correctly fill in your options.");
7474
return;
7575
}
7676

77-
var channel = _client.GetGuild(joinLeave.GuildId).GetTextChannel(joinLeave.ChannelId);
77+
var channel = _client.GetGuild(guildLogging.GuildId)?.GetTextChannel(guildLogging.ChannelId);
7878
if (channel is null)
7979
{
80-
_logger.Error(LogSource.Volte, "Invalid JoinLeaveLog.GuildId/JoinLeaveLog.ChannelId configuration. Check your IDs and try again.");
80+
_logger.Error(LogSource.Volte, "Invalid guild_logging.guild_id/guild_logging.channel_id configuration. Check your IDs and try again.");
8181
return;
8282
}
8383

@@ -100,14 +100,14 @@ await channel.SendMessageAsync(
100100
$"{_client.GetOwner().Mention}: Joined a guild with more bots than users.", false,
101101
e.WithSuccessColor().Build());
102102
else
103-
await channel.SendMessageAsync("", false, e.WithSuccessColor().Build());
103+
await e.WithSuccessColor().SendToAsync(channel);
104104
}
105105

106106
public async Task OnLeaveAsync(LeftGuildEventArgs args)
107107
{
108108
_logger.Debug(LogSource.Volte, "Left a guild.");
109-
if (!Config.JoinLeaveLog.Enabled) return;
110-
var joinLeave = Config.JoinLeaveLog;
109+
if (!Config.GuildLogging.Enabled) return;
110+
var joinLeave = Config.GuildLogging;
111111
if (joinLeave.GuildId is 0 || joinLeave.ChannelId is 0)
112112
{
113113
_logger.Error(LogSource.Volte,

src/Services/LoggingService.cs

+45-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
using System;
22
using System.IO;
3+
using System.Net.Http;
34
using System.Text;
45
using System.Threading.Tasks;
6+
using System.Xml;
57
using Discord;
8+
using Discord.WebSocket;
69
using Gommon;
710
using Humanizer;
11+
using Newtonsoft.Json;
12+
using Newtonsoft.Json.Linq;
13+
using RestSharp;
814
using Volte.Core;
915
using Volte.Core.Models;
1016
using Volte.Core.Models.EventArgs;
@@ -15,8 +21,18 @@ namespace Volte.Services
1521
{
1622
public sealed class LoggingService : VolteEventService
1723
{
24+
private readonly DiscordShardedClient _client;
25+
private readonly HttpClient _http;
26+
private readonly object _lock;
1827
private const string LogFile = "data/Volte.log";
19-
private readonly object _lock = new object();
28+
29+
public LoggingService(DiscordShardedClient discordShardedClient,
30+
HttpClient httpClient)
31+
{
32+
_client = discordShardedClient;
33+
_http = httpClient;
34+
_lock = new object();
35+
}
2036

2137
public override Task DoAsync(EventArgs args)
2238
{
@@ -97,7 +113,7 @@ public void Verbose(LogSource src, string message)
97113
/// </summary>
98114
/// <param name="e">Exception to print.</param>
99115
public void LogException(Exception e)
100-
=> Log(LogSeverity.Error, LogSource.Volte, string.Empty, e);
116+
=> Execute(LogSeverity.Error, LogSource.Volte, string.Empty, e);
101117

102118
private void Execute(LogSeverity s, LogSource src, string message, Exception e)
103119
{
@@ -122,6 +138,7 @@ private void Execute(LogSeverity s, LogSource src, string message, Exception e)
122138
var toWrite = $"{Environment.NewLine}{e.Message}{Environment.NewLine}{e.StackTrace}";
123139
Append(toWrite, Color.IndianRed);
124140
content.Append(toWrite);
141+
LogExceptionInDiscord(e);
125142
}
126143

127144
Console.Write(Environment.NewLine);
@@ -163,5 +180,31 @@ private void Append(string m, Color c)
163180
LogSeverity.Debug => (Color.SandyBrown, "DEBG"),
164181
_ => throw new ArgumentNullException(nameof(severity), "severity cannot be null")
165182
};
183+
184+
private void LogExceptionInDiscord(Exception e)
185+
{
186+
if (!Config.GuildLogging.Enabled) return;
187+
var guildLogging = Config.GuildLogging;
188+
var channel = _client.GetGuild(guildLogging.GuildId)?.GetTextChannel(guildLogging.ChannelId);
189+
if (channel is null)
190+
{
191+
Error(LogSource.Volte, "Invalid guild_logging.guild_id/guild_logging.channel_id configuration. Check your IDs and try again.");
192+
return;
193+
}
194+
195+
_ = Task.Run(async () =>
196+
{
197+
var response = await _http.PostAsync("https://paste.greemdev.net/documents", new StringContent(e.StackTrace, Encoding.UTF8, "text/plain"));
198+
var respObj = JObject.Parse(await response.Content.ReadAsStringAsync());
199+
var url = $"https://paste.greemdev.net/{respObj.GetValue("key")}.cs";
200+
var embed = new EmbedBuilder()
201+
.WithErrorColor()
202+
.WithTitle($"Exception at {DateTimeOffset.UtcNow.FormatDate()}, {DateTimeOffset.UtcNow.FormatFullTime()} UTC")
203+
.AddField("Exception Type", e.GetType(), true)
204+
.AddField("Exception Message", e.Message, true)
205+
.WithDescription($"View the full Stack Trace [here]({url}).");
206+
await embed.SendToAsync(channel);
207+
});
208+
}
166209
}
167210
}

0 commit comments

Comments
 (0)