Adding better error messages to XYShape validator
This commit is contained in:
		
							parent
							
								
									d1ffac492c
								
							
						
					
					
						commit
						03cd887084
					
				|  | @ -584,6 +584,7 @@ module A = { | ||||||
| module A2 = { | module A2 = { | ||||||
|   let fmap = (a, b) => A.fmap(b, a) |   let fmap = (a, b) => A.fmap(b, a) | ||||||
|   let joinWith = (a, b) => A.joinWith(b, a) |   let joinWith = (a, b) => A.joinWith(b, a) | ||||||
|  |   let filter = (a,b) => A.filter(b, a) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module JsArray = { | 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} |   let toJs = (t: t) => {"xs": t.xs, "ys": t.ys} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module Validates = { | module Validator = { | ||||||
|   type t = T.t |   type t = T.t | ||||||
|   let areXsSorted = (t:t) => E.A.Floats.isSorted(T.xs(t)) |   let fnName = "XYShape validate" | ||||||
|   let validate = (t:t) => { |   let property = (propertyName: string): Errors.property => { | ||||||
|     let xsNotSorted = E.A.Floats.isSorted(T.xs(t)) ? None : Some("Xs are not sorted") |     fnName: fnName, | ||||||
|     let xsNotFinite = E.A.Floats.getNonFinite(T.xs(t)) |> E.O.fmap(r => `Xs contain non-finite values: ${E.Float.toString(r)}`) |     propertyName: propertyName, | ||||||
|     let ysNotFinite = E.A.Floats.getNonFinite(T.ys(t)) |> E.O.fmap(r => `Ys contain non-finite values: ${E.Float.toString(r)}`) |   } | ||||||
|  |   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