Skip to content

Commit

Permalink
Merge pull request #1452 from rafaelsc/bugfix/jsonFormater
Browse files Browse the repository at this point in the history
Record stringified property as `""` when `ToString()` returns `null` in JsonFormatters
  • Loading branch information
nblumhardt committed Sep 9, 2020
2 parents d98fca5 + 94d9e1a commit 33f1fd5
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/Serilog/Formatting/Json/JsonFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ protected virtual void WriteJsonProperty(string name, object value, ref string p
[Obsolete(ExtensionPointObsoletionMessage)]
protected virtual void WriteLiteralValue(object value, TextWriter output)
{
WriteString(value.ToString(), output);
WriteString(value.ToString() ?? "", output);
}

void WriteLiteral(object value, TextWriter output, bool forceQuotation = false)
Expand Down
2 changes: 1 addition & 1 deletion src/Serilog/Formatting/Json/JsonValueFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ static void FormatLiteralObjectValue(object value, TextWriter output)
{
if (value == null) throw new ArgumentNullException(nameof(value));

FormatStringValue(value.ToString(), output);
FormatStringValue(value.ToString() ?? "", output);
}

static void FormatStringValue(string str, TextWriter output)
Expand Down
2 changes: 1 addition & 1 deletion test/Serilog.Tests/Formatting/Json/JsonFormatterTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Newtonsoft.Json;
using Newtonsoft.Json;
using Serilog.Events;
using Serilog.Formatting.Json;
using Serilog.Parsing;
Expand Down
75 changes: 75 additions & 0 deletions test/Serilog.Tests/Formatting/Json/JsonValueFormatterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,24 @@ public string Format(object literal)
}

[Theory]
[InlineData(0, "0")]
[InlineData(123, "123")]
[InlineData(-123, "-123")]
[InlineData(123L, "123")]
[InlineData(-123L, "-123")]
[InlineData('c', "\"c\"")]
[InlineData('é', "\"é\"")]
[InlineData('\t', "\"\\t\"")]
[InlineData('\n', "\"\\n\"")]
[InlineData('\0', "\"\\u0000\"")]
[InlineData("Hello, world!", "\"Hello, world!\"")]
[InlineData(true, "true")]
[InlineData(false, "false")]
[InlineData("\\\"\t\r\n\f", "\"\\\\\\\"\\t\\r\\n\\f\"")]
[InlineData("🤷‍", "\"🤷‍\"")]
[InlineData("\u0001", "\"\\u0001\"")]
[InlineData("a\nb", "\"a\\nb\"")]
[InlineData("", "\"\"")]
[InlineData(null, "null")]
public void JsonLiteralTypesAreFormatted(object value, string expectedJson)
{
Expand All @@ -43,7 +54,11 @@ public void DateTimesFormatAsIso8601()
[Fact]
public void DoubleFormatsAsNumber()
{
JsonLiteralTypesAreFormatted(0d, "0");
JsonLiteralTypesAreFormatted(123.0d, "123");
JsonLiteralTypesAreFormatted(-123.0d, "-123");
JsonLiteralTypesAreFormatted(123.45, "123.45");
JsonLiteralTypesAreFormatted(-123.45, "-123.45");
}

[Fact]
Expand All @@ -57,7 +72,11 @@ public void DoubleSpecialsFormatAsString()
[Fact]
public void FloatFormatsAsNumber()
{
JsonLiteralTypesAreFormatted(0f, "0");
JsonLiteralTypesAreFormatted(123.0f, "123");
JsonLiteralTypesAreFormatted(-123.0f, "-123");
JsonLiteralTypesAreFormatted(123.45f, "123.45");
JsonLiteralTypesAreFormatted(-123.45f, "-123.45");
}

[Fact]
Expand All @@ -71,7 +90,44 @@ public void FloatSpecialsFormatAsString()
[Fact]
public void DecimalFormatsAsNumber()
{
JsonLiteralTypesAreFormatted(0m, "0");
JsonLiteralTypesAreFormatted(123.45m, "123.45");
JsonLiteralTypesAreFormatted(-123.45m, "-123.45");
JsonLiteralTypesAreFormatted(123.0m, "123.0");
JsonLiteralTypesAreFormatted(-123.0m, "-123.0");
}

[Fact]
public void TimeSpanFormatsAsString()
{
JsonLiteralTypesAreFormatted(TimeSpan.FromHours(1), "\"01:00:00\"");
JsonLiteralTypesAreFormatted(TimeSpan.FromHours(-1), "\"-01:00:00\"");
JsonLiteralTypesAreFormatted(TimeSpan.Zero, "\"00:00:00\"");
JsonLiteralTypesAreFormatted(TimeSpan.FromDays(1), "\"1.00:00:00\"");
JsonLiteralTypesAreFormatted(TimeSpan.FromDays(-1), "\"-1.00:00:00\"");
JsonLiteralTypesAreFormatted(TimeSpan.MinValue, "\"-10675199.02:48:05.4775808\"");
JsonLiteralTypesAreFormatted(TimeSpan.MaxValue, "\"10675199.02:48:05.4775807\"");
}

[Fact]
public void GuidFormatsAsString()
{
JsonLiteralTypesAreFormatted(Guid.Parse("88c117ae-616c-4bf7-ab58-9c729b15c562"), "\"88c117ae-616c-4bf7-ab58-9c729b15c562\"");
JsonLiteralTypesAreFormatted(Guid.Empty, "\"00000000-0000-0000-0000-000000000000\"");
}

[Fact]
public void ObjectsAreFormattedAsJsonStringViaToString()
{
JsonLiteralTypesAreFormatted(new Exception("This e a Exception"), "\"System.Exception: This e a Exception\"");
JsonLiteralTypesAreFormatted(new AChair(), "\"a chair\"");
JsonLiteralTypesAreFormatted(new ToStringReturnsNull(), "\"\"");
}

[Fact]
public void ObjectsAreFormattedAsExceptionStringsInJsonWhenToStringThrows()
{
Assert.Throws<ArgumentNullException>(() => JsonLiteralTypesAreFormatted(new ToStringThrows(), "will Throws a error before comparing with this string"));
}

static string Format(LogEventPropertyValue value)
Expand Down Expand Up @@ -145,5 +201,24 @@ public void WhenNullNoTypeTagIsWritten()
var f = output.ToString();
Assert.Equal("{}", f);
}

class AChair
{
public string Back => "";
public int[] Legs => null;
public override string ToString() => "a chair";
}

class ToStringReturnsNull
{
public string AProp => "";
public override string ToString() => null;
}

class ToStringThrows
{
public string AProp => "";
public override string ToString() => throw new ArgumentNullException("", "A possible a Bug in a class");
}
}
}

0 comments on commit 33f1fd5

Please sign in to comment.