我正在尝试移植一直使用
Microsoft.WindowsAzure.Storage
类的代码,以使用 Azure.Data.Tables
、Azure.Storage.Queues
等中的较新类。据我所知,StorageException
类已被 取代RequestFailedException
。不幸的是,StorageException
中的一些属性在RequestFailedException
中不存在,使得在遇到异常时很难记录适当的消息(例如:RequestId
、RequestInformation
等)。
迁移文档没有解决
StorageException
和新 RequestFailedException
之间的差异,或者如何从中获取错误详细信息。
似乎新库还不够成熟,无法满足黄金时间,或者可能只是因为文档缺乏相关信息,而我无法找到适当的方法来从
RequestFailedException
获取所有错误信息
.
有谁知道如何从新类中获取更多数据?以下是我们过去所做的一些示例:
catch (StorageException e)
{
operation.Telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
更改上述内容以使用
RequestFailedException
是一个问题,因为 RequestInformation
不是 RequestFailedException
的属性。
这是另一个案例:
catch (StorageException se)
{
var ri = se.RequestInformation;
if (ri.ErrorCode == "TableNotFound")
{
Logger.Info(
$"{SJResult.MakeInfo(64)} {ri.HttpStatusCode} {ri.HttpStatusMessage}, Storage Service code={ri.ErrorCode} This is OK if HL7 has not yet received messages."); // 60240040
}
else
{
Logger.Error(
$"{SJResult.MakeError(65)} HttpStatusCode: {ri.HttpStatusCode}, HttpStatusMessage: {ri.HttpStatusMessage}, Storage Service code={ri.ErrorCode}, " +
$"Extended.ErrorCode: {ri.ExtendedErrorInformation.ErrorCode} Extended.ErrorMessage: {ri.ExtendedErrorInformation.ErrorMessage}"); // E0240041
throw;
}
再次强调,
RequestInformation
在 RequestFailedException
中不可用。
我们如何从新的
RequestInformation
类中获取有关异常的所有详细信息 (RequestFailedException
)?
如您所见,最新版本的azure sdk中RequestFailedException类(Azure)和构造函数的定义。
RequestFailedException(Int32, String, String, Exception) :给出 HTTP 状态代码、指定的错误消息、错误代码以及对 内部异常 的引用。
还有
RequestFailedException(响应)
给出从指定响应获取的错误消息、HTTP状态代码、错误代码。
参数中的 response 表示来自服务的 HTTP 响应,该服务具有
ClientRequestId
作为属性之一,如表中所示,获取发送到服务器的客户端请求 ID形式为 x-ms-client-request-id
headers。您可以在 try-catch 块中捕获错误时尝试相同的操作。
在异常类中你可以给出
public class RequestFailedException : Exception
{
...
public RequestFailedException(int status, string message, string? errorCode, Exception? innerException) : base(message , innerException) { }
}
或者使用 RequestFailedException(Response) 从中可以获得 ClientRequestId。
我自己还没有测试过,但请检查以下参考文献是否可以解决以下问题,或者检查类似的内容是否可以提供想法。另请参阅是否可以检索内容属性作为响应的一部分。
try
{
...
}
catch (Exception aex)
{
foreach (var ex in aex.InnerExceptions)
{
if (ex is RequestFailedException except)
{
var innerException = excep.InnerException;
if (innerException != null && innerException.GetType() == typeof(WebException))
{
WebException webEx = innerException as WebException;
WebResponse resp = webEx.Response;
var responseHeaders = resp.Headers;
string requestId = responseHeaders["x-ms-request-id"];
Console.WriteLine("Request Id: " + requestId);
Console.WriteLine(except.InnerException.Message);
}
else
{
// (not a RequestFailedException)
Console.WriteLine($"{ex.Message}");
}
}
参考资料:
这是我的简单解决方案,有点基于kavya的答案......
catch (Exception ex)
{
if (ex.InnerException is Azure.RequestFailedException rfex)
{
//let's create a custom error message so as not to expose sensitive information to the user
var status = rfex.Status; // ((Azure.RequestFailedException)ex.InnerException).Status;
var errorCode = rfex.ErrorCode; // ((Azure.RequestFailedException)ex.InnerException).ErrorCode;
string exmsg = $"Error is: {ex.Message}\nStatus: {status}\nError Code: {errorCode}";
throw new Exception(exmsg);
}
}