Skip to content

Commit 123412b

Browse files
committed
Update error handlers and messages
1 parent 52d7ad0 commit 123412b

File tree

16 files changed

+84
-77
lines changed

16 files changed

+84
-77
lines changed

JsonSchema/RelogicLabs/JsonSchema/Exceptions/FunctionMismatchException.cs

Lines changed: 0 additions & 11 deletions
This file was deleted.

JsonSchema/RelogicLabs/JsonSchema/Time/DateTimeValidator.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88

99
namespace RelogicLabs.JsonSchema.Time;
1010

11-
internal class DateTimeValidator
11+
internal sealed class DateTimeValidator
1212
{
1313
public const string ISO_8601_DATE = "YYYY-MM-DD";
14-
public const string ISO_8601_TIME = "YYYY-MM-DD'T'hh:mm:ss.fffZZ";
14+
public const string ISO_8601_TIME = "YYYY-MM-DD'T'hh:mm:ss.FZZ";
1515

1616
private static readonly Dictionary<string, SegmentProcessor> _Processors = new();
1717
private readonly DateTimeLexer _dateTimeLexer;
@@ -83,8 +83,9 @@ public void ValidateDate(string input)
8383
public void ValidateTime(string input)
8484
=> Validate(input, new DateTimeContext(DateTimeType.TIME_TYPE));
8585

86-
public bool IsValidDate(string input)
86+
public bool IsValidDate(string input, out string error)
8787
{
88+
error = string.Empty;
8889
try
8990
{
9091
ValidateDate(input);
@@ -93,12 +94,14 @@ public bool IsValidDate(string input)
9394
catch(InvalidDateTimeException ex)
9495
{
9596
DebugUtilities.Print(ex);
97+
error = ex.Message;
9698
return false;
9799
}
98100
}
99101

100-
public bool IsValidTime(string input)
102+
public bool IsValidTime(string input, out string error)
101103
{
104+
error = string.Empty;
102105
try
103106
{
104107
ValidateTime(input);
@@ -107,6 +110,7 @@ public bool IsValidTime(string input)
107110
catch(InvalidDateTimeException ex)
108111
{
109112
DebugUtilities.Print(ex);
113+
error = ex.Message;
110114
return false;
111115
}
112116
}

JsonSchema/RelogicLabs/JsonSchema/Tree/FunctionManager.cs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace RelogicLabs.JsonSchema.Tree;
1111

12-
internal class FunctionManager
12+
internal sealed class FunctionManager
1313
{
1414
private readonly HashSet<string> _includes = new();
1515
private readonly Dictionary<FunctionKey, List<MethodPointer>> _functions = new();
@@ -30,8 +30,8 @@ public void AddClass(string className, Context? context = null)
3030
// if not FunctionBase's subclass
3131
if(!baseclass.IsAssignableFrom(subclass))
3232
throw new InvalidIncludeException(MessageFormatter
33-
.FormatForSchema(CLAS03, $"{subclass.FullName} needs to inherit " +
34-
$"{baseclass.FullName}", context));
33+
.FormatForSchema(CLAS03, $"{subclass.FullName} needs to inherit {
34+
baseclass.FullName}", context));
3535

3636
FunctionBase instance = CreateInstance(subclass, context);
3737
try
@@ -96,7 +96,7 @@ private Dictionary<FunctionKey, List<MethodPointer>> ExtractMethods(
9696
return functions;
9797
}
9898

99-
private int GetParameterCount(ICollection<ParameterInfo> parameters)
99+
private static int GetParameterCount(ICollection<ParameterInfo> parameters)
100100
{
101101
foreach(var p in parameters) if(IsParams(p)) return -1;
102102
return parameters.Count;
@@ -111,29 +111,31 @@ private static bool IsParams(ParameterInfo parameter)
111111
public bool InvokeFunction(JFunction function, JNode target)
112112
{
113113
var methods = GetMethods(function);
114-
string? mismatchMessage = null;
114+
ParameterInfo? mismatchParameter = null;
115+
115116
foreach(var method in methods)
116117
{
117118
var _parameters = method.Parameters;
118119
var _arguments = function.Arguments;
119120
var schemaArgs = ProcessArguments(_parameters, _arguments);
120121
if(schemaArgs == null) continue;
121-
if(!IsMatch(_parameters[0], target))
122-
{
123-
mismatchMessage = $"Function {function.GetOutline()} is applicable on " +
124-
$"{GetTypeName(_parameters[0].ParameterType)} but applied " +
125-
$"on {GetTypeName(target.GetType())} of {target}";
126-
continue;
127-
}
128-
return method.Invoke(function, AddTarget(schemaArgs, target));
122+
if(IsMatch(_parameters[0], target)) return method.Invoke(function,
123+
AddTarget(schemaArgs, target));
124+
mismatchParameter = _parameters[0];
129125
}
130-
if(mismatchMessage != null) return FailWith(new FunctionMismatchException(
131-
MessageFormatter.FormatForSchema(FUNC03, mismatchMessage, function.Context)));
126+
if(mismatchParameter != null)
127+
return FailWith(new JsonSchemaException(new ErrorDetail(FUNC03,
128+
$"Function {function.GetOutline()} is incompatible with the target data type"),
129+
new ExpectedDetail(function, $"applying to a supported data type such as {
130+
GetTypeName(mismatchParameter.ParameterType)}"),
131+
new ActualDetail(target, $"applied to an unsupported data type {
132+
GetTypeName(target.GetType())} of {target}")));
133+
132134
return FailWith(new FunctionNotFoundException(MessageFormatter
133135
.FormatForSchema(FUNC04, function.GetOutline(), function.Context)));
134136
}
135137

136-
private List<object> AddTarget(IList<object> arguments, JNode target)
138+
private static List<object> AddTarget(IList<object> arguments, JNode target)
137139
{
138140
List<object> _arguments = new(1 + arguments.Count) { target };
139141
_arguments.AddRange(arguments);
@@ -152,7 +154,7 @@ private List<MethodPointer> GetMethods(JFunction function)
152154
return methodPointers;
153155
}
154156

155-
private List<object>? ProcessArguments(IList<ParameterInfo> parameters, IList<JNode> arguments)
157+
private static List<object>? ProcessArguments(IList<ParameterInfo> parameters, IList<JNode> arguments)
156158
{
157159
List<object> _arguments = new();
158160
for(int i = 1; i < parameters.Count; i++)

JsonSchema/RelogicLabs/JsonSchema/Types/JAlias.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public override bool Match(JNode node)
1616
{
1717
if(!Runtime.Definitions.ContainsKey(this))
1818
throw new DefinitionNotFoundException(MessageFormatter
19-
.FormatForSchema(DEFI02, $"Definition of {Name} not found", Context));
19+
.FormatForSchema(DEFI02, $"Definition of '{Name}' not found", Context));
2020
return Runtime.Definitions[this].Match(node);
2121
}
2222

JsonSchema/RelogicLabs/JsonSchema/Types/JDataType.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ private JDataType(Builder builder) : base(builder)
2020
JsonType = NonNull(builder.JsonType);
2121
Nested = NonNull(builder.Nested);
2222
Alias = builder.Alias;
23-
Children = ToList(Alias);
23+
Children = AsList(Alias);
2424
}
2525

2626
public override bool Match(JNode node)
@@ -32,11 +32,11 @@ public override bool Match(JNode node)
3232
}
3333

3434
private bool IsMatchCurrent(JNode node)
35-
=> MatchCurrent(node) == Success;
35+
=> MatchCurrent(node, out _) == Success;
3636

37-
private MatchReport MatchCurrent(JNode node)
37+
private MatchReport MatchCurrent(JNode node, out string error)
3838
{
39-
var result = JsonType.Match(node) ? Success : TypeError;
39+
var result = JsonType.Match(node, out error) ? Success : TypeError;
4040
if(Alias == null || result != Success) return result;
4141
Runtime.Definitions.TryGetValue(Alias, out var validator);
4242
if(validator == null) return AliasError;
@@ -60,10 +60,11 @@ internal bool MatchForReport(JNode node)
6060

6161
private bool MatchForReport(JNode node, bool nested)
6262
{
63-
var result = MatchCurrent(node);
63+
var result = MatchCurrent(node, out var error);
6464
if(ReferenceEquals(result, TypeError)) return FailWith(
6565
new JsonSchemaException(
66-
new ErrorDetail(TypeError.GetCode(nested), DataTypeMismatch),
66+
new ErrorDetail(TypeError.GetCode(nested),
67+
FormatMessage(DataTypeMismatch, error)),
6768
ExpectedDetail.AsDataTypeMismatch(this),
6869
ActualDetail.AsDataTypeMismatch(node)));
6970
if(ReferenceEquals(result, AliasError)) return FailWith(
@@ -79,6 +80,9 @@ private bool MatchForReport(JNode node, bool nested)
7980
return true;
8081
}
8182

83+
private static string FormatMessage(string main, string optional)
84+
=> string.IsNullOrEmpty(optional) ? main : $"{main} ({optional.Uncapitalize()})";
85+
8286
public override bool Equals(object? obj)
8387
{
8488
if(ReferenceEquals(null, obj)) return false;
@@ -103,8 +107,8 @@ public string ToString(bool baseForm)
103107
internal new class Builder : JNode.Builder
104108
{
105109
public JsonType? JsonType { get; init; }
106-
public JAlias? Alias { get; init; }
107110
public bool? Nested { get; init; }
111+
public JAlias? Alias { get; init; }
108112
public override JDataType Build() => Build(new JDataType(this));
109113
}
110114
}

JsonSchema/RelogicLabs/JsonSchema/Types/JDefinition.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ private JDefinition(Builder builder) : base(builder)
1212
{
1313
Alias = NonNull(builder.Alias);
1414
Validator = NonNull(builder.Validator);
15-
Children = ToList(Alias, Validator);
15+
Children = AsList<JNode>(Alias, Validator);
1616
}
1717

18-
public override string ToString() => $"{DefineMarker} {Alias} {Validator}";
18+
public override string ToString() => $"{DefineMarker} {Alias}: {Validator}";
1919

2020
internal new class Builder : JNode.Builder
2121
{

JsonSchema/RelogicLabs/JsonSchema/Types/JInclude.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public override bool Equals(object? obj)
2020
}
2121

2222
public override int GetHashCode() => ClassName.GetHashCode();
23-
public override string ToString() => $"{IncludeMarker} {ClassName}";
23+
public override string ToString() => $"{IncludeMarker}: {ClassName}";
2424

2525
internal new class Builder : JNode.Builder
2626
{

JsonSchema/RelogicLabs/JsonSchema/Types/JNode.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public abstract class JNode
1616
public Context Context { get; }
1717
public virtual JNode? Parent => _relations.GetValue(this);
1818
public virtual IEnumerable<JNode> Children
19-
{ get; private protected init; } = Enumerable.Empty<JNode>();
19+
{ get; private protected init; } = Enumerable.Empty<JNode>();
2020
public ParserRuleContext Parser => Context.Parser;
2121
public RuntimeContext Runtime => Context.Runtime;
2222

@@ -26,7 +26,7 @@ private protected JNode(Builder builder)
2626
Context = NonNull(builder.Context);
2727
}
2828

29-
private protected virtual T Initialize<T>() where T : JNode
29+
private T Initialize<T>() where T : JNode
3030
{
3131
foreach(var c in Children) _relations[c] = this;
3232
return (T) this;

JsonSchema/RelogicLabs/JsonSchema/Types/JObject.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ namespace RelogicLabs.JsonSchema.Types;
1010

1111
public sealed class JObject : JComposite
1212
{
13+
private IList<JNode> _components;
1314
public IIndexMap<string, JProperty> Properties { get; }
1415

1516
private JObject(Builder builder) : base(builder)
1617
{
1718
Properties = NonNull(builder.Properties);
19+
_components = Properties.Select(p => p.Value).ToList().AsReadOnly();
1820
Children = Properties.Values;
1921
}
2022

@@ -40,16 +42,14 @@ public override bool Match(JNode node)
4042
ExpectedDetail.AsPropertyNotFound(thisProp),
4143
ActualDetail.AsPropertyNotFound(node, thisProp)));
4244
}
43-
if(unresolved.Count > 0 && !Runtime.IgnoreUndefinedProperties)
45+
if(unresolved.IsEmpty() || Runtime.IgnoreUndefinedProperties) return result;
46+
foreach(var key in unresolved)
4447
{
45-
foreach(var key in unresolved)
46-
{
47-
var property = other.Properties[key];
48-
result &= FailWith(new JsonSchemaException(
49-
new ErrorDetail(PROP06, UndefinedPropertyFound),
50-
ExpectedDetail.AsUndefinedProperty(this, property),
51-
ActualDetail.AsUndefinedProperty(property)));
52-
}
48+
var property = other.Properties[key];
49+
result &= FailWith(new JsonSchemaException(
50+
new ErrorDetail(PROP06, UndefinedPropertyFound),
51+
ExpectedDetail.AsUndefinedProperty(this, property),
52+
ActualDetail.AsUndefinedProperty(property)));
5353
}
5454
return result;
5555
}
@@ -79,11 +79,10 @@ private static bool AreKeysEqual(JProperty? p1, JProperty? p2) {
7979
return p1.Key == p2.Key;
8080
}
8181

82-
private JProperty? GetPropAt(IIndexMap<string, JProperty> properties, int index)
82+
private static JProperty? GetPropAt(IIndexMap<string, JProperty> properties, int index)
8383
=> index >= properties.Count ? null : properties[index];
8484

85-
public override IList<JNode> GetComponents() => Properties.Select(p => p.Value)
86-
.ToList().AsReadOnly();
85+
public override IList<JNode> GetComponents() => _components;
8786

8887
public override bool Equals(object? obj)
8988
{

JsonSchema/RelogicLabs/JsonSchema/Types/JRoot.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ private JRoot(Builder builder) : base(builder)
2424
Pragmas = builder.Pragmas;
2525
Definitions = builder.Definitions;
2626
Value = NonNull(builder.Value);
27-
Children = ToList(ToList(Title, Version), Includes, Pragmas, Definitions, ToList(Value));
27+
Children = new List<JNode>().AddToList(Title, Version)
28+
.AddToList(Includes, Pragmas, Definitions)
29+
.AddToList(Value).AsReadOnly();
2830
}
2931

3032
public override bool Match(JNode node)
@@ -46,7 +48,7 @@ public override string ToString()
4648
return builder.ToString().Trim();
4749
}
4850

49-
private void AppendTo(StringBuilder builder, string? text)
51+
private static void AppendTo(StringBuilder builder, string? text)
5052
{
5153
if(text is null || text.Length == 0) return;
5254
builder.Append(text).Append(NewLine);

0 commit comments

Comments
 (0)