/// <summary> /// Catches an <see cref="Exception"/> and sends its information to this message channel. /// </summary> public static async Task <IUserMessage> CatchAsync(this IMessageChannel channel, Exception ex, StackTraceMode stackTraceMode = StackTraceMode.Simple, RequestOptions options = null, AllowedMentions allowedMentions = null) { var error = new StringBuilder(); error.AppendLine("> **Yikes!**"); error.AppendLine("> An exception has been thrown."); if (ex == null) { return(await channel.SendMessageAsync(error.ToString(), options : options, allowedMentions : allowedMentions)); } if (!string.IsNullOrWhiteSpace(ex.Message)) { error.AppendLine("```"); error.AppendLine(ex.Message); error.Append("```"); } if (string.IsNullOrWhiteSpace(ex.StackTrace) || stackTraceMode == StackTraceMode.None) { return(await channel.SendMessageAsync(error.ToString(), options : options, allowedMentions : allowedMentions)); } error.AppendLine(); error.Append(GetStackTrace(ex.StackTrace, stackTraceMode, error.Length)); return(await channel.SendMessageAsync(error.ToString(), options : options, allowedMentions : allowedMentions)); }
private static string GetStackTrace(string stackTrace, StackTraceMode traceMode, int messageLength) { if (traceMode == StackTraceMode.None || string.IsNullOrWhiteSpace(stackTrace)) { return(null); } var result = new StringBuilder(); result.AppendLine($"> **Stack Trace**"); switch (traceMode) { case StackTraceMode.Simple: if (!StackTracePath.TryParse(stackTrace, out List <StackTracePath> paths)) { return(null); } StackTracePath path = paths.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.Path)) ?? paths.First(); if (path.Method.Length + messageLength + 7 >= 2000) { break; } result.AppendLine($"• at `{path.Method}`"); if (string.IsNullOrWhiteSpace(path.Path)) { break; } string marker = path.LineIndex.HasValue ? $" (Line **{path.LineIndex.Value:##,0}**)" : ""; if (marker.Length + path.Path.Length + messageLength + 7 >= 2000) { break; } result.AppendLine($"• in `{path.Path}`{marker}"); break; default: string[] errorPaths = stackTrace.Split('\n', StringSplitOptions.RemoveEmptyEntries); if (errorPaths.Length == 0 || messageLength + result.Length + errorPaths[0].Length + 8 >= 2000) { break; } result.AppendLine("```bf"); foreach (string errorPath in errorPaths) { if (messageLength + result.Length + errorPath.Length + 3 >= 2000) { break; } result.AppendLine(errorPath); } result.Append("```"); break; } return(result.ToString()); }