namespace MeloongCore.Extensions; public static class ExceptionExtensions { /// /// 返回该异常最底层的 。 /// public static Exception RootException(this Exception ex) { while (ex.InnerException is { } inner) ex = inner; return ex; } /// /// 提取 的详细描述与堆栈信息。返回内容总是多于一行。 /// /// 是否显示所有堆栈,而不是仅与当前。 public static string GetDetail(this Exception? ex, bool onlyRelatedStacks = true) { if (ex is null) return "无可用错误信息!"; return GetSummary(ex, isDetail: true, onlyRelatedStacks); } /// /// 提取 的简要描述,将信息汇总到一行。 /// public static string GetBrief(this Exception? ex) { if (ex is null) return "无可用错误信息!"; return GetSummary(ex, isDetail: false); } /// /// 提取 的描述。 /// public static string GetSummary(Exception ex, bool isDetail, bool onlyRelatedStacks = true) { var innerEx = ex.RootException(); var lines = new List(); bool isInner = false; for (Exception? cur = ex; cur is not null; cur = cur.InnerException) { if (isDetail) { lines.Add((isInner ? "→ " : "") + cur.Message.ReplaceLineEndings("\r\n", true)); if (cur.StackTrace is not null) { foreach (string stack in cur.StackTrace.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries)) { if (onlyRelatedStacks && !stack.ContainsIgnoreCase("pcl")) continue; lines.Add(stack.ReplaceLineEndings("")); } } if (cur.GetType().FullName != "System.Exception") { lines.Add(" 错误类型:" + cur.GetType().FullName); } } else { lines.Add(cur.Message.ReplaceLineEndings(" ", true)); } isInner = true; } string? commonReason = null; if (innerEx is TypeLoadException or BadImageFormatException or MissingMethodException or NotImplementedException or TypeInitializationException) commonReason = "运行环境存在问题。请尝试重新安装 .NET Framework 4.8 然后再试。若无法安装,请先卸载较新版本的 .NET Framework,然后再尝试安装。"; else if (innerEx is UnauthorizedAccessException) commonReason = "权限不足。请尝试右键程序,选择以管理员身份运行,或将文件移动到其他文件夹。"; else if (innerEx is OutOfMemoryException) commonReason = "系统的运行内存不足。请在关闭一部分不需要的程序后再试。"; else if (innerEx is System.Net.Sockets.SocketException && lines.Any(l => l.Contains("WSAStartup"))) commonReason = "请尝试卸载中国移动云盘,然后再试。"; else if (ex.IsNetworkRelated()) commonReason = "你的网络环境不佳,请稍后再试,或使用 VPN 改善网络环境。"; if (isDetail) { if (commonReason is null) { return lines.Join("\r\n"); } else { return commonReason + "\r\n\r\n————————————\r\n详细错误信息:\r\n" + lines.Join("\r\n"); } } else { lines = lines.Distinct().ToList(); if (commonReason is null) { lines.Reverse(); return lines.Join(" ← "); } else { return commonReason + "详细错误:" + lines.First(); } } } /// /// 判断某个 是否为网络连接不良所导致。 /// public static bool IsNetworkRelated(this Exception ex) { // 提取 Message(不能用 GetDetail,因为堆栈的方法参数中就有 timeout 字样) string detail = ""; var cur = ex; detail += cur.Message; while (cur.InnerException is not null) { cur = cur.InnerException; detail += cur.Message; } // 判断 if (detail.Contains("(403)")) return false; return new[] { "(408)", "超时", "timeout", "网络请求失败", "连接尝试失败", "远程主机强迫关闭了", "远程方已关闭传输流", "未能解析此远程名称", "由于目标计算机积极拒绝", "基础连接已经关闭" }.Any(k => detail.ContainsIgnoreCase(k)); } }