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

consider shorting down error message on sequence failure #110

Open
carocad opened this issue Jul 6, 2018 · 10 comments
Open

consider shorting down error message on sequence failure #110

carocad opened this issue Jul 6, 2018 · 10 comments

Comments

@carocad
Copy link

carocad commented Jul 6, 2018

For one of my api endpoints I have a quite long response which is compressed of several so-called steps. Each step is an object on its own.

The problem arises when one of the last item of the validation fails. It seems that expound simply replaces each object in the sequence with ... which is fine for short sequences but for longer ones becomes a problem (See output below)

-- Spec failed --------------------

  {:code ...,
   :uuid ...,
   :waypoints ...,
   :route
   {:distance ...,
    :duration ...,
    :steps
    (...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     ...
     {:mode "transit",
            ^^^^^^^^^
      :maneuver ...,
      :distance ...,
      :duration ...,
      :geometry ...,
      :name ...}
     ...
     ...)}}

should be: "walking"

-- Relevant specs -------

:walk/mode:
  #{"walking"}
:walk/step:
  (clojure.spec.alpha/merge
   (clojure.spec.alpha/keys :req-un [:walk/mode :walk/maneuver])
   :step/base)
:hiposfer.kamal.specs.directions/step:
  (clojure.spec.alpha/or :walk :walk/step :transit :transit/step)
:hiposfer.kamal.specs.directions/steps:
  (clojure.spec.alpha/coll-of
   :hiposfer.kamal.specs.directions/step
   :kind
   clojure.core/sequential?)
:hiposfer.kamal.specs.directions/route:
  (clojure.spec.alpha/keys
   :req-un
   [:hiposfer.kamal.specs.directions/distance
    :hiposfer.kamal.specs.directions/duration
    :hiposfer.kamal.specs.directions/steps])
:hiposfer.kamal.specs.directions/response:
  (clojure.spec.alpha/keys
   :req-un
   [:hiposfer.kamal.specs.directions/code]
   :opt-un
   [:hiposfer.kamal.specs.directions/waypoints
    :hiposfer.kamal.specs.directions/route])
@bhb
Copy link
Owner

bhb commented Jul 7, 2018

Thanks for submitting this! I agree, the output is quite verbose in cases like this. I’ll think more about how I can shorten the output without losing useful context.

@carocad
Copy link
Author

carocad commented Jul 7, 2018

@bhb if I may add. Would it also be possible to add a bit more context to the error report?

In this particular case, :mode "transit" is a key-value pair that is repeated in several steps so the report showing only the failing value is not enough to know exactly which part is failing.

For that I had to switch back to Clojure explain since there I was able to see exactly which values where failing :(

@bhb
Copy link
Owner

bhb commented Jul 8, 2018

Thanks for that additional information! Yes, I’ll also look at how to best add more context in this case.

FWIW, if Expound is omitting too much information, you can use “custom-printer” with “:show-valid-values?” set to true. The API is a bit inconsistent right now (I plan to simplify things for the beta) so let me know if you have any trouble getting this working.

@bhb
Copy link
Owner

bhb commented Jul 8, 2018

@carocad Here's the code for that:

(binding [s/*explain-out* (expound/custom-printer {:show-valid-values? true})]
  (s/explain (s/coll-of int?) [1 2 :3]))
;;-- Spec failed --------------------
;;
;;  [1 2 :3]
;;       ^^
;;
;;should satisfy
;;
;;  int?
;;
;;-------------------------
;;Detected 1 error

I realize that's not intuitive, but I'll be making this easier at some point. Until then, it may be easiest to wrap it up in a function. Hope that helps!

@carocad
Copy link
Author

carocad commented Jul 8, 2018

@bhb Thanks for the info

Using show-valid-values together with the figwheel-theme do improve the situation a bit. However, now the output is gigantic (due to the size of the response that I have) :(

I think that ideally the failing value should show a bit of the context around (enough to know where the problem is) but not the complete datastructure; otherwise the failing value would get lost among the noise.

I know that is a very hard thing to do, though :/

PS: I avoided pasting the error message here, so please let me know if it would help you somehow

@bhb
Copy link
Owner

bhb commented Jul 8, 2018

Yes, it’s a bit tricky. Thanks for letting me know about your use case . It’s very helpful to know which cases need improvement. I’ll think more about this.

@carocad
Copy link
Author

carocad commented Jul 8, 2018

@bhb i just had an idea about how to approach this problem.

Instead of using 'show valid values' I think the concept of depthwould be more appropriate. Basically instead of guessing how much context does a user need to understand the problem, let the user directly tell you.

This is (not by surprise) the same way that most Clojure stacktrace libraries work since those also contain lots of data.

Hope it helps :)

@bhb
Copy link
Owner

bhb commented Jul 8, 2018

Ah, that’s a good idea, thanks!

@kelvinqian00
Copy link
Contributor

I'm also experiencing the same issue as @carocad and my hacked-together solution was simple: capture the printed string from expound/custom-printer with with-out-string, search for empty lines with the following regex:

#"(?<=\n)\s+\.\.\.\n"

and replace each matching string with an empty string. It's a decent solution for my limited use-case, but ideally a similar regex replace would be implemented in the printer itself.

@bhb
Copy link
Owner

bhb commented Aug 7, 2019

@kelvinqian00 Thanks for posting this workaround! I agree this is not ideal. I’m thinking about ways to make this behavior optional.

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

3 participants