简体   繁体   English

检查异常捕获块内的异常类型并记录它

[英]Check for exception type inside Exception catch block and log it

I am using Utf8 json library to deserialize my JSON using DeserializeAsync method of JsonSerializer class.我正在使用 Utf8 json 库使用JsonSerializer类的DeserializeAsync方法反序列化我的 JSON。 And sometimes I am seeing it is throwing exception as -有时我看到它抛出异常 -

Arithmetic operation resulted in an overflow.

So it looks like my JSON data has a value that's too large to fit in one of our object's properties causing this overflow exception.因此,看起来我的 JSON 数据的值太大而无法放入我们对象的属性之一,从而导致此溢出异常。 Below is the code I had originally and we weren't catching any exception being thrown from below code -下面是我最初的代码,我们没有捕获从下面的代码抛出的任何异常 -

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);
    }
}

So now I wrapped my above code in a try catch so that I can catch the exception instead of throwing it and log the body of the request as well -所以现在我将上面的代码包装在 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);
        }
    }
}

Problem Statement问题陈述

I wanted to see if there is any way to combine above two catch block and write it in one inside Exception block?我想看看是否有任何方法可以将上面的两个 catch 块组合起来并将其写在一个Exception块中? I tried with below code but it complains on this line ex.GetUnderlyingByteArrayUnsafe() as it cannot find GetUnderlyingByteArrayUnsafe method for it.我尝试使用下面的代码,但它在这一行上抱怨ex.GetUnderlyingByteArrayUnsafe()因为它找不到GetUnderlyingByteArrayUnsafe方法。 My idea is to log the request if it cannot deserialize the json and write in one catch block if possible.我的想法是记录请求,如果它不能反序列化 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);
}

Also I was looking at the Utf8 json git repo and I don't see DeserializeAsync method throws any JsonParsingException exception?另外我在看 Utf8 json git repo ,我没有看到DeserializeAsync方法抛出任何JsonParsingException异常?

The is operator is performing a boolean operation on whether or not your exception can be converted to the target type, but that type conversion is not then passed to the first branch of your ternary. is运算符正在对您的异常是否可以转换为目标类型执行布尔运算,但该类型转换不会传递到您的三元组的第一个分支。

You can either recast:您可以重铸:

var bodyString = ex is JsonParsingException 
    ? ((JsonParsingException)ex).GetUnderlyingByteArrayUnsafe() 
    : null;

Or you can use the as operator which will attempt to make the conversion for you and if it cannot, will return null:或者您可以使用as运算符,它会尝试为您进行转换,如果不能,将返回 null:

var jsonParsingException = ex as JsonParsingException;
var bodyString = jsonParsingException != null
    ? jsonParsingException.GetUnderlyingByteArrayUnsafe() 
    : null;

Note that with C#7 pattern matching , you can also output the result to a temporary local variable and enable a one-liner:请注意,使用C#7 模式匹配,您还可以将结果输出到临时局部变量并启用单行:

var bodyString = ex is JsonParsingException j
    ? j.GetUnderlyingByteArrayUnsafe() 
    : null;

and finally, @mjwills pointed out that you can wrap the as operation in braces and check for null with the null propagation operator, allowing for a one-liner as well:最后,@mjwills 指出您可以将 as 操作包装在大括号中,并使用空传播运算符检查空值,也允许单行:

var bodyString = (ex as JsonParsingException)?.GetUnderlyingByteArrayUnsafe();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM