I am using Utf8 json library to deserialize my JSON using DeserializeAsync method of JsonSerializer class. 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. 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 -
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? I tried with below code but it complains on this line ex.GetUnderlyingByteArrayUnsafe() as it cannot find GetUnderlyingByteArrayUnsafe method for it. My idea is to log the request if it cannot deserialize the json and write in one catch block if possible.
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?
The
isoperator 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.You can either recast:
Or you can use the
asoperator which will attempt to make the conversion for you and if it cannot, will return null:Note that with C#7 pattern matching, you can also output the result to a temporary local variable and enable a one-liner:
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: