add support for transparent schema errors with multiple child errors (#654)
This commit is contained in:
parent
674ceea74e
commit
807868f440
|
@ -61,10 +61,29 @@ against the error message (more fragile):
|
|||
```
|
||||
|
||||
Error messages may contain special tokens:
|
||||
* `@value` is replaced with the error's value field (which is usually the original field value, but
|
||||
not always).
|
||||
* If the validation error has exactly one sub-error and the message is set to `$transparent`, the
|
||||
sub-error will be displayed instead. (The sub-error itself may be set to `$transparent`, etc.)
|
||||
|
||||
* The `@value` token is replaced with the error's value field. This is usually (but not always) the
|
||||
original field value.
|
||||
* When an error has child errors, by default they're flattened into one message:
|
||||
```
|
||||
line | field | error
|
||||
---- | ---------- | -------------------------------------------------------------------------
|
||||
4 | Changes[0] | JSON does not match schema from 'then'.
|
||||
| | ==> Changes[0].ToArea.Y: Invalid type. Expected Integer but got String.
|
||||
| | ==> Changes[0].ToArea: Missing required fields: Height.
|
||||
```
|
||||
|
||||
If you set the message for an error to `$transparent`, the parent error is omitted entirely and
|
||||
the child errors are shown instead:
|
||||
```
|
||||
line | field | error
|
||||
---- | ------------------- | ----------------------------------------------
|
||||
8 | Changes[0].ToArea.Y | Invalid type. Expected Integer but got String.
|
||||
8 | Changes[0].ToArea | Missing required fields: Height.
|
||||
```
|
||||
|
||||
The child errors themselves may be marked `$transparent`, etc. If an error has no child errors,
|
||||
this override is ignored.
|
||||
|
||||
Caveats:
|
||||
* To override an error from a `then` block, the `@errorMessages` must be inside the `then` block
|
||||
|
|
|
@ -46,6 +46,9 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
/// <summary>The schema ID to use if none was specified.</summary>
|
||||
private string DefaultSchemaID = "manifest";
|
||||
|
||||
/// <summary>A token in an error message which indicates that the child errors should be displayed instead.</summary>
|
||||
private readonly string TransparentToken = "$transparent";
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
|
@ -124,7 +127,7 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
// validate JSON
|
||||
parsed.IsValid(schema, out IList<ValidationError> rawErrors);
|
||||
var errors = rawErrors
|
||||
.Select(this.GetErrorModel)
|
||||
.SelectMany(this.GetErrorModels)
|
||||
.ToArray();
|
||||
return this.View("Index", result.AddErrors(errors));
|
||||
}
|
||||
|
@ -205,21 +208,25 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Get a flattened representation representation of a schema validation error and any child errors.</summary>
|
||||
/// <summary>Get view models representing a schema validation error and any child errors.</summary>
|
||||
/// <param name="error">The error to represent.</param>
|
||||
private JsonValidatorErrorModel GetErrorModel(ValidationError error)
|
||||
private IEnumerable<JsonValidatorErrorModel> GetErrorModels(ValidationError error)
|
||||
{
|
||||
// skip through transparent errors
|
||||
while (this.GetOverrideError(error) == "$transparent" && error.ChildErrors.Count == 1)
|
||||
error = error.ChildErrors[0];
|
||||
if (this.GetOverrideError(error) == this.TransparentToken && error.ChildErrors.Any())
|
||||
{
|
||||
foreach (var model in error.ChildErrors.SelectMany(this.GetErrorModels))
|
||||
yield return model;
|
||||
yield break;
|
||||
}
|
||||
|
||||
// get message
|
||||
string message = this.GetOverrideError(error);
|
||||
if (message == null)
|
||||
if (message == null || message == this.TransparentToken)
|
||||
message = this.FlattenErrorMessage(error);
|
||||
|
||||
// build model
|
||||
return new JsonValidatorErrorModel(error.LineNumber, error.Path, message, error.ErrorType);
|
||||
yield return new JsonValidatorErrorModel(error.LineNumber, error.Path, message, error.ErrorType);
|
||||
}
|
||||
|
||||
/// <summary>Get a flattened, human-readable message for a schema validation error and any child errors.</summary>
|
||||
|
@ -229,11 +236,11 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
{
|
||||
// get override
|
||||
string message = this.GetOverrideError(error);
|
||||
if (message != null)
|
||||
if (message != null && message != this.TransparentToken)
|
||||
return message;
|
||||
|
||||
// skip through transparent errors
|
||||
while (this.GetOverrideError(error) == "$transparent" && error.ChildErrors.Count == 1)
|
||||
while (this.GetOverrideError(error) == this.TransparentToken && error.ChildErrors.Count == 1)
|
||||
error = error.ChildErrors[0];
|
||||
|
||||
// get friendly representation of main error
|
||||
|
|
Loading…
Reference in New Issue