检查 Exception catch 块内的异常类型并记录它
Check for exception type inside Exception catch block and log it
我正在使用 Utf8 json 库使用 JsonSerializer
class 的 DeserializeAsync
方法反序列化我的 JSON。有时我看到它抛出异常 -
Arithmetic operation resulted in an overflow.
所以看起来我的 JSON 数据的值太大而无法放入我们对象的属性之一,从而导致此溢出异常。下面是我最初的代码,我们没有捕获到从下面的代码中抛出的任何异常 -
using (var content = httpResponseMessage.Content)
{
if (content == null) return (default(T), statusCode);
using (var responseStream = await httpResponseMessage.Content.ReadAsStreamAsync())
{
deserializedValue = await JsonSerializer.DeserializeAsync<T>(responseStream, formatResolver);
}
}
所以现在我将上面的代码包装在一个 try catch 中,这样我就可以捕获异常而不是抛出它并记录请求的主体 -
using (var content = httpResponseMessage.Content)
{
if (content == null) return (default(T), statusCode);
using (var responseStream = await httpResponseMessage.Content.ReadAsStreamAsync())
{
try
{
deserializedValue = await JsonSerializer.DeserializeAsync<T>(responseStream, formatResolver);
}
catch (JsonParsingException ex)
{
var bodyString = ex.GetUnderlyingByteArrayUnsafe();
var error = (bodyString != null) ? $"Failing json: {bodyString}" : null;
logger.logError(error, ex.Message, "Deserialization Exception", ex.StackTrace, (int)statusCode);
return (default(T), HttpStatusCode.BadRequest);
}
catch (Exception ex)
{
logger.logError("Cannot Deserialize JSON", ex.Message, "Deserialization Exception", ex.StackTrace, (int)statusCode);
return (default(T), HttpStatusCode.BadRequest);
}
}
}
问题陈述
我想看看有没有办法把上面的两个catch块合并起来写在Exception
块里面?我尝试使用以下代码,但它在这一行 ex.GetUnderlyingByteArrayUnsafe()
上抱怨,因为它找不到 GetUnderlyingByteArrayUnsafe
方法。我的想法是,如果无法反序列化 json 并在可能的情况下写入一个 catch 块,则记录该请求。
catch (Exception ex)
{
var bodyString = ex is JsonParsingException? ex.GetUnderlyingByteArrayUnsafe() : null;
var error = (bodyString != null) ? $"Failing json: {bodyString}" : "Cannot Deserialize JSON";
logger.logError(error, ex.Message, "Deserialization Exception", ex.StackTrace, (int)statusCode);
return (default(T), HttpStatusCode.BadRequest);
}
我也在查看 Utf8 json git repo,但我没有看到 DeserializeAsync
方法抛出任何 JsonParsingException
异常?
is
运算符正在对您的异常是否可以转换为目标类型执行布尔运算,但该类型转换不会随后传递给您的三元组的第一个分支。
您可以重铸:
var bodyString = ex is JsonParsingException
? ((JsonParsingException)ex).GetUnderlyingByteArrayUnsafe()
: null;
或者您可以使用 as
运算符,它将尝试为您进行转换,如果不能,将 return null:
var jsonParsingException = ex as JsonParsingException;
var bodyString = jsonParsingException != null
? jsonParsingException.GetUnderlyingByteArrayUnsafe()
: null;
请注意,使用C#7 pattern matching,您还可以将结果输出到临时局部变量并启用one-liner:
var bodyString = ex is JsonParsingException j
? j.GetUnderlyingByteArrayUnsafe()
: null;
最后,@mjwills 指出您可以将 as 操作包裹在大括号中并使用 null 传播运算符检查 null,同时允许 one-liner:
var bodyString = (ex as JsonParsingException)?.GetUnderlyingByteArrayUnsafe();
我正在使用 Utf8 json 库使用 JsonSerializer
class 的 DeserializeAsync
方法反序列化我的 JSON。有时我看到它抛出异常 -
Arithmetic operation resulted in an overflow.
所以看起来我的 JSON 数据的值太大而无法放入我们对象的属性之一,从而导致此溢出异常。下面是我最初的代码,我们没有捕获到从下面的代码中抛出的任何异常 -
using (var content = httpResponseMessage.Content)
{
if (content == null) return (default(T), statusCode);
using (var responseStream = await httpResponseMessage.Content.ReadAsStreamAsync())
{
deserializedValue = await JsonSerializer.DeserializeAsync<T>(responseStream, formatResolver);
}
}
所以现在我将上面的代码包装在一个 try catch 中,这样我就可以捕获异常而不是抛出它并记录请求的主体 -
using (var content = httpResponseMessage.Content)
{
if (content == null) return (default(T), statusCode);
using (var responseStream = await httpResponseMessage.Content.ReadAsStreamAsync())
{
try
{
deserializedValue = await JsonSerializer.DeserializeAsync<T>(responseStream, formatResolver);
}
catch (JsonParsingException ex)
{
var bodyString = ex.GetUnderlyingByteArrayUnsafe();
var error = (bodyString != null) ? $"Failing json: {bodyString}" : null;
logger.logError(error, ex.Message, "Deserialization Exception", ex.StackTrace, (int)statusCode);
return (default(T), HttpStatusCode.BadRequest);
}
catch (Exception ex)
{
logger.logError("Cannot Deserialize JSON", ex.Message, "Deserialization Exception", ex.StackTrace, (int)statusCode);
return (default(T), HttpStatusCode.BadRequest);
}
}
}
问题陈述
我想看看有没有办法把上面的两个catch块合并起来写在Exception
块里面?我尝试使用以下代码,但它在这一行 ex.GetUnderlyingByteArrayUnsafe()
上抱怨,因为它找不到 GetUnderlyingByteArrayUnsafe
方法。我的想法是,如果无法反序列化 json 并在可能的情况下写入一个 catch 块,则记录该请求。
catch (Exception ex)
{
var bodyString = ex is JsonParsingException? ex.GetUnderlyingByteArrayUnsafe() : null;
var error = (bodyString != null) ? $"Failing json: {bodyString}" : "Cannot Deserialize JSON";
logger.logError(error, ex.Message, "Deserialization Exception", ex.StackTrace, (int)statusCode);
return (default(T), HttpStatusCode.BadRequest);
}
我也在查看 Utf8 json git repo,但我没有看到 DeserializeAsync
方法抛出任何 JsonParsingException
异常?
is
运算符正在对您的异常是否可以转换为目标类型执行布尔运算,但该类型转换不会随后传递给您的三元组的第一个分支。
您可以重铸:
var bodyString = ex is JsonParsingException
? ((JsonParsingException)ex).GetUnderlyingByteArrayUnsafe()
: null;
或者您可以使用 as
运算符,它将尝试为您进行转换,如果不能,将 return null:
var jsonParsingException = ex as JsonParsingException;
var bodyString = jsonParsingException != null
? jsonParsingException.GetUnderlyingByteArrayUnsafe()
: null;
请注意,使用C#7 pattern matching,您还可以将结果输出到临时局部变量并启用one-liner:
var bodyString = ex is JsonParsingException j
? j.GetUnderlyingByteArrayUnsafe()
: null;
最后,@mjwills 指出您可以将 as 操作包裹在大括号中并使用 null 传播运算符检查 null,同时允许 one-liner:
var bodyString = (ex as JsonParsingException)?.GetUnderlyingByteArrayUnsafe();