Giter Club home page Giter Club logo

Comments (13)

neuecc avatar neuecc commented on June 2, 2024 3

private class is not supported in StandardResolver.Default.
You can use/configure AllowPrivate resolver.

You can see configuration guide: https://github.com/neuecc/Utf8Json#resolver

from utf8json.

neuecc avatar neuecc commented on June 2, 2024 1

JSON.NET extracts data from GetObjectData(SerializationInfo info, StreamingContext context).
The standard exception class correctly implements to ISerializable.
However, normal custom exceptions will be ignored.
And it has many unused data.

Anyway, it is right that you want to serialize public properties of exceptions.
I'll try it.

from utf8json.

NimaAra avatar NimaAra commented on June 2, 2024

Okay, changing to

JsonSerializer.Serialize(stream, payload, StandardResolver.AllowPrivateCamelCase);

is now giving me:
System.ArgumentException: 'The type 'System.Void*' may not be used as a type argument.'

from utf8json.

neuecc avatar neuecc commented on June 2, 2024

Thanks, for reason currently no support Exception on default.
I think, I should support it.

workaround, you can make custom formatter.

public class ExceptionFormatter : IJsonFormatter<Exception>
{
    // normally serializer uses `GetObjectData(SerializationInfo info, StreamingContext context)` but I don't like it.
    public void Serialize(ref JsonWriter writer, Exception value, IJsonFormatterResolver formatterResolver)
    {
        writer.WriteBeginObject();

        writer.WritePropertyName("Message"); // TODO:cache encoded property
        writer.WriteString(value.Message);
        writer.WriteValueSeparator();

        writer.WritePropertyName("Source");
        writer.WriteString(value.Source);
        writer.WriteValueSeparator();

        writer.WritePropertyName("StackTrace");
        writer.WriteString(value.StackTrace);
        writer.WriteValueSeparator();

        writer.WriteEndObject();
    }

    public Exception Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
    {
        throw new NotImplementedException();
    }
}

and use it.

Utf8Json.Resolvers.CompositeResolver.RegisterAndSetAsDefault(new[] { new ExceptionFormatter() }, new[] { StandardResolver.AllowPrivate });

from utf8json.

NimaAra avatar NimaAra commented on June 2, 2024

That's a shame, I don't want to be serializing an entire object graph as Exception can have nested InnerExceptions each having their own set of properties that may not be consistent across different Exception types.

I guess I will have to wait for now until you add the support for it.

from utf8json.

neuecc avatar neuecc commented on June 2, 2024

JSON.NET's serialized data is here.

public class FooException:Exception
{
    public int Bar { get; set; }
}

var ex = new Exception("ABC", new FooException { Bar = 100 });
var json = Newtonsoft.Json.JsonConvert.SerializeObject(ex, Newtonsoft.Json.Formatting.Indented);
{
  "ClassName": "System.Exception",
  "Message": "ABC",
  "Data": null,
  "InnerException": {
    "ClassName": "ConsoleApp169.FooException",
    "Message": null,
    "Data": null,
    "InnerException": null,
    "HelpURL": null,
    "StackTraceString": null,
    "RemoteStackTraceString": null,
    "RemoteStackIndex": 0,
    "ExceptionMethod": null,
    "HResult": -2146233088,
    "Source": null,
    "WatsonBuckets": null
  },
  "HelpURL": null,
  "StackTraceString": null,
  "RemoteStackTraceString": null,
  "RemoteStackIndex": 0,
  "ExceptionMethod": null,
  "HResult": -2146233088,
  "Source": null,
  "WatsonBuckets": null
}

What data do you expect?
This is the fixed ExceptionFormatter.

public class ExceptionFormatter : IJsonFormatter<Exception>
{
    public void Serialize(ref JsonWriter writer, Exception value, IJsonFormatterResolver formatterResolver)
    {
        writer.WriteBeginObject();

        writer.WritePropertyName("Message"); // TODO:cache encoded property
        writer.WriteString(value.Message);
        writer.WriteValueSeparator();

        writer.WritePropertyName("Source");
        writer.WriteString(value.Source);
        writer.WriteValueSeparator();

        writer.WritePropertyName("StackTrace");
        writer.WriteString(value.StackTrace);
            
        if (value.InnerException != null)
        {
            writer.WriteValueSeparator();
            writer.WritePropertyName("InnerException");
            formatterResolver.GetFormatter<Exception>().Serialize(ref writer, value.InnerException, formatterResolver);
        }

        writer.WriteEndObject();
    }

    public Exception Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
    {
        throw new NotSupportedException("Exception formatter does not support deserialize.");
    }
}
{
  "Message": "ABC",
  "Source": null,
  "StackTrace": null,
  "InnerException": {
    "Message": "ConsoleApp169.FooException'...",
    "Source": null,
    "StackTrace": null
  }
}

It can serialize inner exception.
How about this one?

from utf8json.

neuecc avatar neuecc commented on June 2, 2024

I've add exception support, it includes ClassName, Message, Source, StackTrace, InnerException.

{
  "ClassName": "System.Exception",
  "Message": "ABC",
  "Source": null,
  "StackTrace": null,
  "InnerException": {
    "ClassName": "FooException",
    "Message": "Exception of type 'FooException' was thrown.",
    "Source": null,
    "StackTrace": null
  }
}

from utf8json.

neuecc avatar neuecc commented on June 2, 2024

I've uploaded v.1.3.5, it includes this improvement.

from utf8json.

NimaAra avatar NimaAra commented on June 2, 2024

Thank you for the quick release, we are almost getting there!

Given the following:

var argNull = new ArgumentNullException("Age", "oops");
var ex = new Exception("Something Went Wrong", argNull);

Has the following structure:

Utf8Json fails to serialize the ParamName property furthermore it skips others.

In my opinion, Json.NET is serializing too many properties and limiting this to public ones should suffice. Can you serialize all the public properties including the ones in the inner Exception(s)? My use case requires the exception to be serialized as a whole so that it can be restructured on the client side at a later date.

Json.NET:

{
  "ClassName": "System.Exception",
  "Message": "Something Went Wrong",
  "Data": {},
  "InnerException": {
    "ClassName": "System.ArgumentNullException",
    "Message": "oops",
    "Data": {},
    "InnerException": null,
    "HelpURL": null,
    "StackTraceString": null,
    "RemoteStackTraceString": null,
    "RemoteStackIndex": 0,
    "ExceptionMethod": null,
    "HResult": -2147467261,
    "Source": null,
    "WatsonBuckets": null,
    "ParamName": "Age"
  },
  "HelpURL": null,
  "StackTraceString": null,
  "RemoteStackTraceString": null,
  "RemoteStackIndex": 0,
  "ExceptionMethod": null,
  "HResult": -2146233088,
  "Source": null,
  "WatsonBuckets": null
}

Utf8Json:

{
  "ClassName": "System.Exception",
  "Message": "Something Went Wrong",
  "Source": null,
  "StackTrace": null,
  "InnerException": {
    "ClassName": "System.ArgumentNullException",
    "Message": "oops\r\nParameter name: Age",
    "Source": null,
    "StackTrace": null
  }
}

from utf8json.

neuecc avatar neuecc commented on June 2, 2024

I've upload ver 1.3.6, it supports public members and resolver configuration.

var ex = new Exception("ABC", new FooException { Bar = 100 });
var json = JsonSerializer.ToJsonString(ex, Utf8Json.Resolvers.StandardResolver.ExcludeNullSnakeCase);
Console.WriteLine(JsonSerializer.PrettyPrint(json));
{
  "class_name": "System.Exception",
  "message": "ABC",
  "inner_exception": {
    "class_name": "FooException",
    "bar": 100,
    "message": "Exception of type 'FooException' was thrown."
  }
}

from utf8json.

NimaAra avatar NimaAra commented on June 2, 2024

Thanks, still some issues. Given the following:

public sealed class Entry
{
    public int Number { get; set; }
    public Exception Exception { get; set; }
}

var argNullEx = new ArgumentNullException("cooCoo", "parameter cannot be null");
var payload = new Entry
{
    Number = 1,		
    Exception = argNullEx
};

var json1 = Utf8Json.JsonSerializer.ToJsonString(payload, StandardResolver.AllowPrivateCamelCase);
var json2 = JsonConvert.SerializeObject(payload);

Which gives:

UTF8Json
{
  "number": 1,
  "exception": {
    "className": "System.Exception",
    "message": "parameter cannot be null\r\nParameter name: cooCoo",
    "stackTrace": null,
    "source": null,
    "innerException": null
  }
} 

Json.NET
{
  "Number": 1,
  "Exception": {
    "ClassName": "System.ArgumentNullException",
    "Message": "parameter cannot be null",
    "Data": null,
    "InnerException": null,
    "HelpURL": null,
    "StackTraceString": null,
    "RemoteStackTraceString": null,
    "RemoteStackIndex": 0,
    "ExceptionMethod": null,
    "HResult": -2147467261,
    "Source": null,
    "WatsonBuckets": null,
    "ParamName": "cooCoo"
  }
} 

As you can see:

  • className name is incorrect
  • paramName is missing

However, if I do:

var argNullEx = new ArgumentNullException("cooCoo", "parameter cannot be null");	
var appEx = new ApplicationException("CiaoCiao", argNullEx);
var payload = new Entry
{
    Number = 1,		
    Exception = appEx
};

Then I get the paramName and the correct className for the inner exception but I still get invalid className for the ApplicationException:

UTF8Json
{
  "number": 1,
  "exception": {
    "className": "System.Exception",
    "message": "CiaoCiao",
    "stackTrace": null,
    "source": null,
    "innerException": {
      "className": "System.ArgumentNullException",
      "message": "parameter cannot be null\r\nParameter name: cooCoo",
      "paramName": "cooCoo",
      "stackTrace": null,
      "source": null,
      "innerException": null
    }
  }
} 

Json.NET
{
  "Number": 1,
  "Exception": {
    "ClassName": "System.ApplicationException",
    "Message": "CiaoCiao",
    "Data": null,
    "InnerException": {
      "ClassName": "System.ArgumentNullException",
      "Message": "parameter cannot be null",
      "Data": null,
      "InnerException": null,
      "HelpURL": null,
      "StackTraceString": null,
      "RemoteStackTraceString": null,
      "RemoteStackIndex": 0,
      "ExceptionMethod": null,
      "HResult": -2147467261,
      "Source": null,
      "WatsonBuckets": null,
      "ParamName": "cooCoo"
    },
    "HelpURL": null,
    "StackTraceString": null,
    "RemoteStackTraceString": null,
    "RemoteStackIndex": 0,
    "ExceptionMethod": null,
    "HResult": -2146232832,
    "Source": null,
    "WatsonBuckets": null
  }
} 

from utf8json.

neuecc avatar neuecc commented on June 2, 2024

Ok, I've uploaded new v1.3.6.1 it always serializes concrete exception type.

from utf8json.

NimaAra avatar NimaAra commented on June 2, 2024

Works great, thanks for that.

I will open a separate issue for the CamelCase mutation.

from utf8json.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.