MessagePack-CSharp / MessagePack-CSharp/MessagePack-CSharp
Null value received in a custom formatter for Exception
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
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- 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