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

Extend -compile-model for reitit.coercsion.spec #683

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jonasseglare
Copy link

This PR extends the -compile-model method in the reitit.coercion.spec namespace to work for one more special case: If the model parameter contains more than one spec but they are all equal, then the merged spec is trivially any of those specs.

Background

We encountered the following error when trying to instantiate our router:

{:message "Can't merge nested clojure specs",
 :spec [#object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"]
        #object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"]]}

So, what it means is that it fails to merge model if it is

[clojure.core/any? clojure.core/any?]

We can fix this by observing that because it is a vector with the same element being repeated many times, the merged version would trivially be that element, in this case clojure.core/any?.

See relevant part of exception with stack trace:

clojure.lang.ExceptionInfo: :reitit.coercion.spec/model-error
clojure.lang.ExceptionInfo: :reitit.coercion.spec/model-error

{:message "Can't merge nested clojure specs", :spec [#object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"] #object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"]]}
{:type :reitit.coercion.spec/model-error, :data {:message "Can't merge nested clojure specs", :spec [#object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"] #object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"]]}, :reitit.exception/cause #error {
 :cause ":reitit.coercion.spec/model-error"
 :data {:type :reitit.coercion.spec/model-error, :data {:message "Can't merge nested clojure specs", :spec [#object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"] #object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"]]}}
 :via
 [{:type clojure.lang.ExceptionInfo
   :message ":reitit.coercion.spec/model-error"
   :data {:type :reitit.coercion.spec/model-error, :data {:message "Can't merge nested clojure specs", :spec [#object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"] #object[clojure.core$any_QMARK_ 0x19105a87 "clojure.core$any_QMARK_@19105a87"]]}}
   :at [reitit.exception$fail_BANG_ invokeStatic "exception.cljc" 8]}]
 :trace
 [[reitit.exception$fail_BANG_ invokeStatic "exception.cljc" 8]
  [reitit.exception$fail_BANG_ invoke "exception.cljc" 4]
  [reitit.coercion.spec$create$reify__71053 _compile_model "spec.cljc" 126]
  [reitit.ring$_compile_coercion$fn__71903 invoke "ring.cljc" 56]
  [reitit.impl$_path_vals$_path_vals__68882$fn__68884 invoke "impl.cljc" 31]
  [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
  [clojure.core.protocols$fn__8230 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8230 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8178$G__8173__8191 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6887]
  [clojure.core$reduce invoke "core.clj" 6869]
  [reitit.impl$_path_vals$_path_vals__68882 invoke "impl.cljc" 26]
  [reitit.impl$_path_vals$_path_vals__68882$fn__68884 invoke "impl.cljc" 32]
  [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
  [clojure.core.protocols$fn__8230 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8230 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8178$G__8173__8191 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6887]
  [clojure.core$reduce invoke "core.clj" 6869]
  [reitit.impl$_path_vals$_path_vals__68882 invoke "impl.cljc" 26]
  [reitit.impl$_path_vals$_path_vals__68882$fn__68884 invoke "impl.cljc" 32]
  [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
  [clojure.core.protocols$fn__8230 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8230 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8178$G__8173__8191 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6887]
  [clojure.core$reduce invoke "core.clj" 6869]
  [reitit.impl$_path_vals$_path_vals__68882 invoke "impl.cljc" 26]
  [reitit.impl$_path_vals invokeStatic "impl.cljc" 35]
  [reitit.impl$_path_vals invoke "impl.cljc" 24]
  [reitit.impl$path_update invokeStatic "impl.cljc" 41]
  [reitit.impl$path_update invoke "impl.cljc" 40]
  [reitit.ring$_compile_coercion invokeStatic "ring.cljc" 56]
  [reitit.ring$_compile_coercion invoke "ring.cljc" 55]
  [reitit.ring$compile_result$__GT_endpoint__71916 invoke "ring.cljc" 64]
  [reitit.ring$compile_result$fn__71923 invoke "ring.cljc" 81]
  [clojure.lang.PersistentArrayMap kvreduce "PersistentArrayMap.java" 429]
  [clojure.core$fn__8525 invokeStatic "core.clj" 6909]
  [clojure.core$fn__8525 invoke "core.clj" 6889]
  [clojure.core.protocols$fn__8257$G__8252__8266 invoke "protocols.clj" 175]
  [clojure.core$reduce_kv invokeStatic "core.clj" 6920]
  [clojure.core$reduce_kv invoke "core.clj" 6911]
  [reitit.ring$compile_result invokeStatic "ring.cljc" 78]
  [reitit.ring$compile_result invoke "ring.cljc" 58]
  [reitit.impl$compile_route invokeStatic "impl.cljc" 163]
  [reitit.impl$compile_route invoke "impl.cljc" 162]
  [reitit.impl$compile_routes$fn__69035 invoke "impl.cljc" 166]
  [clojure.core$keep$fn__8649 invoke "core.clj" 7406]
  [clojure.lang.LazySeq sval "LazySeq.java" 42]
  [clojure.lang.LazySeq seq "LazySeq.java" 51]
  [clojure.lang.RT seq "RT.java" 535]
  [clojure.core$seq__5467 invokeStatic "core.clj" 139]
  [clojure.core.protocols$seq_reduce invokeStatic "protocols.clj" 24]
  [clojure.core.protocols$fn__8236 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8236 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8178$G__8173__8191 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6887]
  [clojure.core$into invokeStatic "core.clj" 6959]
  [clojure.core$into invoke "core.clj" 6951]
  [reitit.impl$compile_routes invokeStatic "impl.cljc" 166]
  [reitit.impl$compile_routes invoke "impl.cljc" 165]
  [reitit.core$router invokeStatic "core.cljc" 346]
  [reitit.core$router invoke "core.cljc" 317]
  [reitit.ring$router invokeStatic "ring.cljc" 134]
  [reitit.ring$router invoke "ring.cljc" 104]
  [jobtech_taxonomy.api.handler$app invokeStatic "handler.clj" 27]
  [jobtech_taxonomy.api.handler$app invoke "handler.clj" 25]
  [clojure.lang.AFn applyToHelper "AFn.java" 154]

@opqdonut
Copy link
Member

opqdonut commented Aug 9, 2024

This seems like a great feature! Could you please add a test case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🇰‍🇼 Waiting
Development

Successfully merging this pull request may close these issues.

2 participants