Skip to content

Enum deserialization exception is not very helpful #1614

@sicklittlemonkey

Description

@sicklittlemonkey

Expected Behavior

For a response where the following class is serialized:

public class Config
{
    public List<Option> Options { get; set; }
}

With server-side code:

public enum Option
{
    Zero,
    One,
    Two,
    Three
};

And a client-side bug:

public enum Option
{
    Zero,
    One,
    Two
    // Three is missing
};

I would hope to get a meaningful exception.

Actual Behavior

The exception tells me about the internals of RestSharp, not about the type being deserialized:

Value cannot be null.
Parameter name: item

Specifications

  • Version: Any recent version including 106.12.0 and dev branch
  • Platform: Windows 10

StackTrace

System.ArgumentNullException
   at System.ThrowHelper.IfNullAndNullsAreIllegalThenThrow[T](Object value, ExceptionArgument argName)
   at System.Collections.Generic.List`1.System.Collections.IList.Add(Object item)
   at RestSharp.Serialization.Json.JsonSerializer.BuildList(Type type, Object parent)
   at RestSharp.Serialization.Json.JsonSerializer.ConvertValue(TypeInfo typeInfo, Object value)
   at RestSharp.Serialization.Json.JsonSerializer.Map(Object target, IDictionary`2 data)
   at RestSharp.Serialization.Json.JsonSerializer.CreateAndMap(Type type, Object element)
   at RestSharp.Serialization.Json.JsonSerializer.ConvertValue(TypeInfo typeInfo, Object value)
   at RestSharp.Serialization.Json.JsonSerializer.Deserialize[T](IRestResponse response)
   at RestSharp.RestClient.Deserialize[T](IRestRequest request, IRestResponse raw)

So the code path is:
\RestSharp\src\RestSharp\Serializers\Json\JsonSerializer.cs

    IList BuildList(Type type, object? parent) {
    // ...
                    var item = ConvertValue(itemType.GetTypeInfo(), element);

                    list.Add(item); // ** Thrown here because item is null. **

\RestSharp\src\RestSharp\Serializers\Json\JsonSerializer.cs

    object? ConvertValue(TypeInfo typeInfo, object? value) {
    // ...
        if (typeInfo.IsEnum) return type.FindEnumValue(stringValue, Culture);
\RestSharp\src\RestSharp\Extensions\ReflectionExtensions.cs
    public static object? FindEnumValue(this Type type, string value, CultureInfo culture)
    // ...
        return ret; // ** Returns the null which will cause the exception **

Possible fix

It would be nice to return information that the caller could use to identify the problem. Different info is available at different levels in the stack, and devs more familiar with the RestSharp codebase could craft something elegant. But the simplest change would seem to be something like a null check at the end of FindEnumValue():

    if (ret == null)
        throw new ArgumentOutOfRangeException(value + " undefined for " + type);
    return ret;

Which gives an exception message such as:

Exception: Specified argument was out of the range of valid values.
Parameter name: 3 undefined for Option

I can submit this as a PR if desired, though it's trivial and you'll likely want to change something.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions