Adding better error messages to XYShape validator
This commit is contained in:
parent
d1ffac492c
commit
03cd887084
|
@ -584,6 +584,7 @@ module A = {
|
|||
module A2 = {
|
||||
let fmap = (a, b) => A.fmap(b, a)
|
||||
let joinWith = (a, b) => A.joinWith(b, a)
|
||||
let filter = (a,b) => A.filter(b, a)
|
||||
}
|
||||
|
||||
module JsArray = {
|
||||
|
|
29
packages/squiggle-lang/src/rescript/Utility/Errors.res
Normal file
29
packages/squiggle-lang/src/rescript/Utility/Errors.res
Normal file
|
@ -0,0 +1,29 @@
|
|||
type property = {fnName: string, propertyName: string}
|
||||
|
||||
type rec error =
|
||||
| NotSorted(property)
|
||||
| IsEmpty(property)
|
||||
| NotFinite(property, float)
|
||||
| DifferentLengths({fnName: string, p1Name: string, p2Name: string, p1Length: int, p2Length: int})
|
||||
| Multiple(array<error>)
|
||||
|
||||
let mapErrorArrayToError = (errors: array<error>): option<error> => {
|
||||
switch errors {
|
||||
| [] => None
|
||||
| [error] => Some(error)
|
||||
| _ => Some(Multiple(errors))
|
||||
}
|
||||
}
|
||||
|
||||
let rec toString = (t: error) =>
|
||||
switch t {
|
||||
| NotSorted({fnName, propertyName}) => `${fnName} ${propertyName} is not sorted`
|
||||
| IsEmpty({fnName, propertyName}) => `${fnName} ${propertyName} is empty`
|
||||
| NotFinite({fnName, propertyName}, exampleValue) =>
|
||||
`${fnName} ${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}`
|
||||
| DifferentLengths({fnName, p1Name, p2Name, p1Length, p2Length}) =>
|
||||
`${fnName} ${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString(
|
||||
p1Length,
|
||||
)} and ${p2Name} has length ${E.I.toString(p2Length)}`
|
||||
| Multiple(errors) => `Multiple Errors: ${E.A2.fmap(errors, toString) |> E.A.joinWith(", ")}`
|
||||
}
|
|
@ -62,13 +62,39 @@ module T = {
|
|||
let toJs = (t: t) => {"xs": t.xs, "ys": t.ys}
|
||||
}
|
||||
|
||||
module Validates = {
|
||||
module Validator = {
|
||||
type t = T.t
|
||||
let areXsSorted = (t:t) => E.A.Floats.isSorted(T.xs(t))
|
||||
let validate = (t:t) => {
|
||||
let xsNotSorted = E.A.Floats.isSorted(T.xs(t)) ? None : Some("Xs are not sorted")
|
||||
let xsNotFinite = E.A.Floats.getNonFinite(T.xs(t)) |> E.O.fmap(r => `Xs contain non-finite values: ${E.Float.toString(r)}`)
|
||||
let ysNotFinite = E.A.Floats.getNonFinite(T.ys(t)) |> E.O.fmap(r => `Ys contain non-finite values: ${E.Float.toString(r)}`)
|
||||
let fnName = "XYShape validate"
|
||||
let property = (propertyName: string): Errors.property => {
|
||||
fnName: fnName,
|
||||
propertyName: propertyName,
|
||||
}
|
||||
let notSortedError = (p: string): Errors.error => NotSorted(property(p))
|
||||
let notFiniteError = (p, exampleValue): Errors.error => NotFinite(property(p), exampleValue)
|
||||
let isEmptyError = (propertyName): Errors.error => IsEmpty(property(propertyName))
|
||||
let differentLengthsError = (t): Errors.error => DifferentLengths({
|
||||
fnName: fnName,
|
||||
p1Name: "Xs",
|
||||
p2Name: "Ys",
|
||||
p1Length: E.A.length(T.xs(t)),
|
||||
p2Length: E.A.length(T.ys(t)),
|
||||
})
|
||||
|
||||
let areXsSorted = (t: t) => E.A.Floats.isSorted(T.xs(t))
|
||||
let areXsEmpty = (t: t) => E.A.length(t.xs) == 0
|
||||
let getNonFiniteXs = (t: t) => t->T.xs->E.A.Floats.getNonFinite
|
||||
let getNonFiniteYs = (t: t) => t->T.ys->E.A.Floats.getNonFinite
|
||||
|
||||
let validate = (t: t) => {
|
||||
let xsNotSorted = areXsSorted(t) ? None : Some(notSortedError("Xs"))
|
||||
let xsEmpty = areXsEmpty(t) ? None : Some(isEmptyError("Xs"))
|
||||
let differentLengths =
|
||||
E.A.length(T.xs(t)) !== E.A.length(T.ys(t)) ? Some(differentLengthsError(t)) : None
|
||||
let xsNotFinite = getNonFiniteXs(t)->E.O2.fmap(notFiniteError("Xs"))
|
||||
let ysNotFinite = getNonFiniteYs(t)->E.O2.fmap(notFiniteError("Ys"))
|
||||
[xsNotSorted, xsEmpty, differentLengths, xsNotFinite, ysNotFinite]
|
||||
->E.A.O.concatSomes
|
||||
->Errors.mapErrorArrayToError
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user