This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -10,8 +11,6 @@ namespace Just.Railway;
|
|||||||
[JsonDerivedType(typeof(ManyErrors))]
|
[JsonDerivedType(typeof(ManyErrors))]
|
||||||
public abstract class Error : IEquatable<Error>, IComparable<Error>
|
public abstract class Error : IEquatable<Error>, IComparable<Error>
|
||||||
{
|
{
|
||||||
private IDictionary<string, object>? _extensionData;
|
|
||||||
|
|
||||||
protected internal Error(){}
|
protected internal Error(){}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -77,28 +76,8 @@ public abstract class Error : IEquatable<Error>, IComparable<Error>
|
|||||||
|
|
||||||
[Pure] public abstract string Type { get; }
|
[Pure] public abstract string Type { get; }
|
||||||
[Pure] public abstract string Message { get; }
|
[Pure] public abstract string Message { get; }
|
||||||
[Pure, JsonExtensionData] public IDictionary<string, object> ExtensionData
|
[Pure, JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ImmutableDictionary<string, string>? ExtensionData { get; init; }
|
||||||
{
|
[Pure] public string? this[string key] => ExtensionData?.TryGetValue(key, out var value) == true ? value : null;
|
||||||
get => _extensionData ??= new Dictionary<string, object>();
|
|
||||||
init => _extensionData = value ?? new Dictionary<string, object>();
|
|
||||||
}
|
|
||||||
[Pure] public object? this[string name]
|
|
||||||
{
|
|
||||||
get => _extensionData?.TryGetValue(name, out var val) == true ? val : null;
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value is null)
|
|
||||||
{
|
|
||||||
_extensionData?.Remove(name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_extensionData ??= new Dictionary<string, object>();
|
|
||||||
_extensionData[name] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Pure, JsonIgnore] public abstract int Count { get; }
|
[Pure, JsonIgnore] public abstract int Count { get; }
|
||||||
[Pure, JsonIgnore] public abstract bool IsEmpty { get; }
|
[Pure, JsonIgnore] public abstract bool IsEmpty { get; }
|
||||||
@@ -199,13 +178,13 @@ public sealed class ExceptionalError : Error
|
|||||||
: this(exception.GetType().Name, exception.Message)
|
: this(exception.GetType().Name, exception.Message)
|
||||||
{
|
{
|
||||||
Exception = exception;
|
Exception = exception;
|
||||||
FillExtensionData(exception);
|
ExtensionData = ExtractExtensionData(exception);
|
||||||
}
|
}
|
||||||
internal ExceptionalError(string message, Exception exception)
|
internal ExceptionalError(string message, Exception exception)
|
||||||
: this(exception.GetType().Name, message)
|
: this(exception.GetType().Name, message)
|
||||||
{
|
{
|
||||||
Exception = exception;
|
Exception = exception;
|
||||||
FillExtensionData(exception);
|
ExtensionData = ExtractExtensionData(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
@@ -231,15 +210,28 @@ public sealed class ExceptionalError : Error
|
|||||||
yield return this;
|
yield return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillExtensionData(Exception exception)
|
private static ImmutableDictionary<string, string>? ExtractExtensionData(Exception exception)
|
||||||
{
|
{
|
||||||
|
if (!(exception.Data?.Count > 0))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
List<KeyValuePair<string, string>>? values = null;
|
||||||
|
|
||||||
foreach (var key in exception.Data.Keys)
|
foreach (var key in exception.Data.Keys)
|
||||||
{
|
{
|
||||||
|
if (key is null) continue;
|
||||||
|
|
||||||
var value = exception.Data[key];
|
var value = exception.Data[key];
|
||||||
if (key is null || value is null)
|
if (value is null) continue;
|
||||||
continue;
|
|
||||||
this.ExtensionData[key.ToString() ?? string.Empty] = value;
|
var keyString = key.ToString();
|
||||||
|
var valueString = value.ToString();
|
||||||
|
if (string.IsNullOrEmpty(keyString) || string.IsNullOrEmpty(valueString)) continue;
|
||||||
|
|
||||||
|
values ??= [];
|
||||||
|
values.Add(new(keyString, valueString));
|
||||||
}
|
}
|
||||||
|
return values?.ToImmutableDictionary();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Railway.Tests.Errors;
|
namespace Railway.Tests.Errors;
|
||||||
|
|
||||||
public class Serialization
|
public class Serialization
|
||||||
@@ -8,9 +10,8 @@ public class Serialization
|
|||||||
// Given
|
// Given
|
||||||
Error many_errors = new ManyErrors(new Error[]{
|
Error many_errors = new ManyErrors(new Error[]{
|
||||||
new ExpectedError("err1", "msg1"){
|
new ExpectedError("err1", "msg1"){
|
||||||
ExtensionData = {
|
ExtensionData = ImmutableDictionary<string, string>.Empty
|
||||||
["ext"] = "ext_value"
|
.Add("ext", "ext_value"),
|
||||||
}
|
|
||||||
},
|
},
|
||||||
new ExceptionalError(new Exception("msg2")),
|
new ExceptionalError(new Exception("msg2")),
|
||||||
});
|
});
|
||||||
@@ -18,7 +19,7 @@ public class Serialization
|
|||||||
var result = JsonSerializer.Serialize(many_errors);
|
var result = JsonSerializer.Serialize(many_errors);
|
||||||
// Then
|
// Then
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
expected: "[{\"$$err\":0,\"Type\":\"err1\",\"Message\":\"msg1\",\"ext\":\"ext_value\"},{\"$$err\":1,\"Type\":\"Exception\",\"Message\":\"msg2\"}]",
|
expected: "[{\"$$err\":0,\"Type\":\"err1\",\"Message\":\"msg1\",\"ExtensionData\":{\"ext\":\"ext_value\"}},{\"$$err\":1,\"Type\":\"Exception\",\"Message\":\"msg2\"}]",
|
||||||
result);
|
result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ public class Serialization
|
|||||||
public void WhenDeserializingManyErrors()
|
public void WhenDeserializingManyErrors()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var json = "[{\"$$err\":0,\"Type\":\"err1\",\"Message\":\"msg1\",\"ext\":\"ext_value\"},{\"$$err\":1,\"Type\":\"Exception\",\"Message\":\"msg2\"}]";
|
var json = "[{\"$$err\":0,\"Type\":\"err1\",\"Message\":\"msg1\",\"ExtensionData\":{\"ext1\":\"ext_value1\",\"ext2\":\"ext_value2\"}},{\"$$err\":1,\"Type\":\"Exception\",\"Message\":\"msg2\"}]";
|
||||||
// When
|
// When
|
||||||
var result = JsonSerializer.Deserialize<Error[]>(json);
|
var result = JsonSerializer.Deserialize<Error[]>(json);
|
||||||
// Then
|
// Then
|
||||||
@@ -39,7 +40,10 @@ public class Serialization
|
|||||||
result
|
result
|
||||||
);
|
);
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
expected: "ext_value",
|
expected: "ext_value1",
|
||||||
result[0].ExtensionData["ext"].ToString());
|
result[0]["ext1"]);
|
||||||
|
Assert.Equal(
|
||||||
|
expected: "ext_value2",
|
||||||
|
result[0]["ext2"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user