MessagePack-CSharp / MessagePack-CSharp/MessagePack-CSharp

Null value received in a custom formatter for Exception

Abierto
#2,001 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
C#
Estrellas
6.8k
Forks
775
Merge medio
3 h 26 min
PR fusionados (30 d)
6

Descripción

#### Bug description

When trying to serialize/deserialize an exception object using TypelessContractlessStandardResolver, some details like StackTrace and Source are getting lost on the deserialized object.
Hence, I tried to write a custom IMessagePackFormatter. There are two scenarios now :

1. Serialize an exception with no inner exception

The value parameter received in Serialize method is always null

2. Serialize an exception with inner exception

The value parameter received in Serialize method is the inner exception and not the actual exception that was passed for serialization

As a result, I am not able to get a workaround even with a custom IMessagePackFormatter.

#### Repro steps

- Add a custom IMessagePackFormatter
```
internal class ExceptionFormatter : IMessagePackFormatter
{
public Exception Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{

}

public void Serialize(ref MessagePackWriter writer, Exception value, MessagePackSerializerOptions options)
{
/// value is null here if exception has no inner exception else inner exception instead of actual exception passed for serialization
}
}
```

- Configure a custom resolver to use the custom ExceptionFormatter
```

interface ISerializer
{
byte[] Serialize(object obj);

T Deserialize(byte[] bytes);
}

public class MessagePackTypeLessSerializer : ISerializer
{
private static MessagePackSerializerOptions serializerOptions;
static MessagePackTypeLessSerializer()
{
var resolver = CompositeResolver.Create(
[new ExceptionFormatter()],
[TypelessContractlessStandardResolver.Instance]);
serializerOptions = MessagePackSerializerOptions.Standard.WithResolver(resolver); ;
}

public byte[] Serialize(object obj)
{
return MessagePackSerializer.Typeless.Serialize(obj, serializerOptions);
}

public T Deserialize(byte[] bytes)
{
if (MessagePackSerializer.Typeless.Deserialize(bytes, serializerOptions) is T result)
{
return result;
}
throw new ArgumentException($"Deserialized object is not of type {typeof(T)}");
}

}
```
- Throw an exception and try to serialize

```
ISerializer serializer = new MessagePackContractLessSerializer();
var exception = GetException();
var exceptionSerialized = serializer.Serialize(exception);

Exception GetException()
{
try
{
throw new InvalidOperationException("Invalid Operation");
//throw new InvalidOperationException("Invalid Operation", new ArgumentException("Inner Exception"));
}
catch (Exception ex)
{
return ex;
}
}

```

#### Expected behavior

Correct exception object should be received in Serialize method of the IMessagePackFormatter that was passed for serialization.

#### Actual behavior

null/inner exception object is received in Serialize method of the IMessagePackFormatter instead of actual exception passed for serialization.

#### Version used:
.Net Core 8.0 , MessagePack 2.5.172 : **Broken**
.Net Framework 4.7, MessagePack 2.5.172 : **Partly broken** (When no inner exception, we get the correct value. Same as .net core when there is inner exception)

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza reproduciendo el escenario de IMessagePackFormatter personalizado con TypelessContractlessStandardResolver y las MessagePackSerializerOptions mostradas en el issue, comparando el comportamiento de .NET Core 8.0 y .NET Framework 4.7. Sigue la ruta de serialización typeless y del resolver para determinar por qué Serialize recibe null o la excepción interna; se considera terminado cuando el formatter recibe el objeto Exception original en ambos casos.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
csharp
Área
backend
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
38/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.