为何Contains方法无法捕获异常中的‘Could not create SSL/TLS secure channel’内容?
我尝试简化日志中的异常输出:当捕获到包含“Could not create SSL/TLS secure channel”的异常时,用自定义信息替代完整异常内容,但Exception.ToString().Contains()方法未按预期匹配到该字符串,尽管异常输出中明确存在该短语。
异常信息
!Dropbox Success Message: System.AggregateException: One or more errors occurred. ---> System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel. at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) --- End of inner exception stack trace --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Dropbox.Api.DropboxRequestHandler.d__18.MoveNext() --- End of stack trace from previous location where exception was thrown ---
实现代码
catch (Exception e) { if (e.ToString().Contains("Could not create SSL/TLS secure channel")) { _report.Add($"!Exception occurred in SendToDropbox."); _report.Add($"!Could not create SSL/TLS secure channel."); } else { _report.Add($"!Exception occurred in SendToDropbox."); _report.Add($"!{e}"); } }
请问为何Contains方法无法捕获该内容?我哪里操作有误?
核心原因
你当前的实现存在两个关键问题:
- 依赖
ToString()的文本匹配不可靠:Exception.ToString()的输出包含堆栈跟踪、嵌套异常信息,可能存在不可见控制字符(如制表符、换行符),或因.NET版本、本地化设置导致文本格式细微差异,直接用Contains()匹配容易失效。 - 未正确处理嵌套异常结构:捕获的最外层异常是
AggregateException,它包裹了HttpRequestException,而目标异常信息实际存在于最内层的WebException中。虽然ToString()会输出所有层级内容,但字符串匹配的鲁棒性极差。
正确解决方案
不要通过文本匹配判断异常类型,而是递归遍历异常链,直接检查异常的类型和消息内容,这样更可靠:
catch (Exception e) { var hasSslError = HasSslTlsSecureChannelError(e); if (hasSslError) { _report.Add($"!Exception occurred in SendToDropbox."); _report.Add($"!Could not create SSL/TLS secure channel."); } else { _report.Add($"!Exception occurred in SendToDropbox."); _report.Add($"!{e}"); } } // 递归遍历异常链,检查是否包含目标SSL/TLS错误 private bool HasSslTlsSecureChannelError(Exception ex) { if (ex == null) return false; // 检查当前异常的消息是否包含目标字符串(忽略大小写,提升鲁棒性) if (ex.Message.IndexOf("Could not create SSL/TLS secure channel", StringComparison.OrdinalIgnoreCase) >= 0) return true; // 处理AggregateException的多个内部异常 if (ex is AggregateException aggEx) { foreach (var innerEx in aggEx.InnerExceptions) { if (HasSslTlsSecureChannelError(innerEx)) return true; } } // 递归检查单个内部异常 return HasSslTlsSecureChannelError(ex.InnerException); }
额外优化
如果需要更精准的判断,可以直接检查WebException的状态:
// 在辅助方法中添加: if (ex is WebException webEx && webEx.Status == WebExceptionStatus.RequestCanceled && webEx.Message.Contains("Could not create SSL/TLS secure channel")) { return true; }
内容的提问来源于stack exchange,提问作者SomeoneSpecial

