Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

explain doesn't return all errors for sequence schemas #411

Closed
DaveWM opened this issue Apr 7, 2021 · 4 comments
Closed

explain doesn't return all errors for sequence schemas #411

DaveWM opened this issue Apr 7, 2021 · 4 comments

Comments

@DaveWM
Copy link

DaveWM commented Apr 7, 2021

Hi, I've run into some unexpected (but not necessarily incorrect) behaviour when calling malli/explain with sequence schemas. It seems to stop searching for errors after encountering an invalid element, whereas I'd expect it to return all errors, including errors due to too few/many elements.

For example, if you run (malli/explain [:repeat {:max 1} int?] ["a"]) you get:

{:schema [:repeat {:max 1} int?],
 :value ["a"],
 :errors (#Error{:path [0], :in [0], :schema int?, :value "a"}
          #Error{:path [], :in [0], :schema [:repeat {:max 1} int?], :value "a", :type :malli.core/input-remaining})}

;; output of malli.error/humanize
[["should be an int" "input remaining"]]

I'd expect to see the first error, but not the second (:malli.core/input-remaining). You also get the reverse problem when there are too few elements in a sequence, for example running (malli/explain [:repeat {:min 2} int?] ["a"]) you get:

{:schema [:repeat {:min 2} int?], :value ["a"], :errors (#Error{:path [0], :in [0], :schema int?, :value "a"})}
;; output of malli.error/humanize
[["should be an int"]]

Here I'd expect a second error with type :malli.core/end-of-input.

Is this working as expected? If not, if you could point me to roughly the area of the code I need to change, I'll attempt to make a PR :)

@nilern
Copy link
Contributor

nilern commented Apr 7, 2021

In the first case the "input remaining" comes is due to the fact that [] is a prefix of ["a"] that [:repeat {:max 1} int?] does match.

In the second case there is no chance to run out of input because "a" does not match int?. In general getting also the out of input error would require an error-correcting parser (like in batch-mode compilers) which would be based on heuristics and potentially complicated. With just :repeat it would be easy but on the other hand you should just use [:sequential {:min 2} int?] in such a simple case.

So it is working as intended but really it answers "where would parse fail?" while your expectations are, not unreasonably, in terms of higher level input validation.

The relevant code is in malli.impl.regex.

@DaveWM
Copy link
Author

DaveWM commented Apr 7, 2021

So it is working as intended but really it answers "where would parse fail?" while your expectations are, not unreasonably, in terms of higher level input validation.

That makes sense, I'll close this issue. Thanks!

Do you have any plans to implement that higher level input validation? My use case is that I'm trying to generate a human-readable message when schema validation fails, ideally describing all the ways in which the input doesn't match the schema.

@DaveWM DaveWM closed this as completed Apr 7, 2021
@nilern
Copy link
Contributor

nilern commented Apr 8, 2021

Do you have any plans to implement that higher level input validation?

Not that I know of. I suspect it would get complicated and only benefit your use case (which is quite common, though).

The complications would be limited to explain, so another layer would not be necessary. On the other hand the JS bundle size could become an issue with that approach.

#387 would also require resynchronization after invalid elements like in your second example so maybe these are piling up..?

ideally describing all the ways in which the input doesn't match the schema

Except in your first example where just "should be an int" would be ideal 😄

@DaveWM
Copy link
Author

DaveWM commented Apr 8, 2021

OK, thanks for you help @nilern!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants