From 674ceea74e74c5b0f432534dba981b5066ea7630 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 6 Aug 2019 03:19:38 -0400 Subject: add support for transparent schema errors (#654) --- .../Controllers/JsonValidatorController.cs | 89 ++++++++++++++-------- 1 file changed, 57 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/SMAPI.Web/Controllers/JsonValidatorController.cs b/src/SMAPI.Web/Controllers/JsonValidatorController.cs index c23103dd..cd0a6439 100644 --- a/src/SMAPI.Web/Controllers/JsonValidatorController.cs +++ b/src/SMAPI.Web/Controllers/JsonValidatorController.cs @@ -124,7 +124,7 @@ namespace StardewModdingAPI.Web.Controllers // validate JSON parsed.IsValid(schema, out IList rawErrors); var errors = rawErrors - .Select(error => new JsonValidatorErrorModel(error.LineNumber, error.Path, this.GetFlattenedError(error), error.ErrorType)) + .Select(this.GetErrorModel) .ToArray(); return this.View("Index", result.AddErrors(errors)); } @@ -175,35 +175,6 @@ namespace StardewModdingAPI.Web.Controllers return response; } - /// Get a flattened, human-readable message representing a schema validation error. - /// The error to represent. - /// The indentation level to apply for inner errors. - private string GetFlattenedError(ValidationError error, int indent = 0) - { - // get override error - string message = this.GetOverrideError(error); - if (message != null) - return message; - - // get friendly representation of main error - message = error.Message; - switch (error.ErrorType) - { - case ErrorType.Enum: - message = $"Invalid value. Found '{error.Value}', but expected one of '{string.Join("', '", error.Schema.Enum)}'."; - break; - - case ErrorType.Required: - message = $"Missing required fields: {string.Join(", ", (List)error.Value)}."; - break; - } - - // add inner errors - foreach (ValidationError childError in error.ChildErrors) - message += "\n" + "".PadLeft(indent * 2, ' ') + $"==> {childError.Path}: " + this.GetFlattenedError(childError, indent + 1); - return message; - } - /// Get a normalised schema name, or the if blank. /// The raw schema name to normalise. private string NormaliseSchemaName(string schemaName) @@ -234,6 +205,60 @@ namespace StardewModdingAPI.Web.Controllers return null; } + /// Get a flattened representation representation of a schema validation error and any child errors. + /// The error to represent. + private JsonValidatorErrorModel GetErrorModel(ValidationError error) + { + // skip through transparent errors + while (this.GetOverrideError(error) == "$transparent" && error.ChildErrors.Count == 1) + error = error.ChildErrors[0]; + + // get message + string message = this.GetOverrideError(error); + if (message == null) + message = this.FlattenErrorMessage(error); + + // build model + return new JsonValidatorErrorModel(error.LineNumber, error.Path, message, error.ErrorType); + } + + /// Get a flattened, human-readable message for a schema validation error and any child errors. + /// The error to represent. + /// The indentation level to apply for inner errors. + private string FlattenErrorMessage(ValidationError error, int indent = 0) + { + // get override + string message = this.GetOverrideError(error); + if (message != null) + return message; + + // skip through transparent errors + while (this.GetOverrideError(error) == "$transparent" && error.ChildErrors.Count == 1) + error = error.ChildErrors[0]; + + // get friendly representation of main error + message = error.Message; + switch (error.ErrorType) + { + case ErrorType.Const: + message = $"Invalid value. Found '{error.Value}', but expected '{error.Schema.Const}'."; + break; + + case ErrorType.Enum: + message = $"Invalid value. Found '{error.Value}', but expected one of '{string.Join("', '", error.Schema.Enum)}'."; + break; + + case ErrorType.Required: + message = $"Missing required fields: {string.Join(", ", (List)error.Value)}."; + break; + } + + // add inner errors + foreach (ValidationError childError in error.ChildErrors) + message += "\n" + "".PadLeft(indent * 2, ' ') + $"==> {childError.Path}: " + this.FlattenErrorMessage(childError, indent + 1); + return message; + } + /// Get an override error from the JSON schema, if any. /// The schema validation error. private string GetOverrideError(ValidationError error) @@ -254,12 +279,12 @@ namespace StardewModdingAPI.Web.Controllers string[] parts = pair.Key.Split(':', 2); if (parts[0].Equals(error.ErrorType.ToString(), StringComparison.InvariantCultureIgnoreCase) && Regex.IsMatch(error.Message, parts[1])) - return pair.Value; + return pair.Value?.Trim(); } // match by type if (errors.TryGetValue(error.ErrorType.ToString(), out string message)) - return message; + return message?.Trim(); return null; } -- cgit