From 4225f272c674d82c76a5e36f365b6260e1281d83 Mon Sep 17 00:00:00 2001 From: Yannick Scherer Date: Wed, 22 Mar 2017 10:09:32 +0100 Subject: [PATCH] throw an exception on input coercion failures. Previously, the generated error containers were passed to resolvables in place of the actual parameter values. This should now be fixed. Fixes alumbra/alumbra#17. --- src/alumbra/claro/coercion.clj | 25 ++++++++++++++++++------- test/alumbra/claro/coercion_test.clj | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/alumbra/claro/coercion.clj b/src/alumbra/claro/coercion.clj index a30756c..65ba122 100644 --- a/src/alumbra/claro/coercion.clj +++ b/src/alumbra/claro/coercion.clj @@ -10,7 +10,12 @@ (data/error (format "could not coerce value to '%s': %s" type-name - (pr-str value)))))) + (pr-str value)) + {:value value + :type-name type-name + :throwable (format "[%s] %s" + (.getName (class t)) + (.getMessage t))})))) (defn- wrap-coercer-exception [f type-name] @@ -52,9 +57,15 @@ (defn coerce-value [{:keys [schema scalars]} type-name value] - (-> (or (get-in scalars [type-name :decode]) - (let [{:keys [type->kind]} schema] - (if (= (type->kind type-name) :enum) - csk/->kebab-case-keyword - #(default-coercer type-name %)))) - (call-coercer type-name value))) + (let [result (-> (or (get-in scalars [type-name :decode]) + (let [{:keys [type->kind]} schema] + (if (= (type->kind type-name) :enum) + csk/->kebab-case-keyword + #(default-coercer type-name %)))) + (call-coercer type-name value))] + (if (data/error? result) + (throw + (ex-info + (data/error-message result) + (data/error-data result))) + result))) diff --git a/test/alumbra/claro/coercion_test.clj b/test/alumbra/claro/coercion_test.clj index 7c197b0..5b8eca4 100644 --- a/test/alumbra/claro/coercion_test.clj +++ b/test/alumbra/claro/coercion_test.clj @@ -3,6 +3,7 @@ [properties :as prop] [generators :as gen] [clojure-test :refer [defspec]]] + [clojure.test :refer :all] [camel-snake-kebab.core :as csk] [claro.data :as data] [alumbra.claro.fixtures :as fix])) @@ -173,3 +174,27 @@ (execute!) (get-in [:data "result"]))] (output-valid? result))))) + +(deftest t-input-coercion-exception + (let [decode #(throw (ex-info "oops." {:value %})) + encode str + execute! (fix/execute-fn + {:schema schema + :query {:as-id (->Identity nil (constantly true))} + :scalars {"ID" {:encode encode, :decode decode}}})] + (is (thrown-with-msg? + clojure.lang.ExceptionInfo + #"could not coerce value to 'ID'" + (execute! "{ asId(v: 10) }"))))) + +(deftest t-output-coercion-exception + (let [decode str + encode #(throw (ex-info "oops." {:value %})) + execute! (fix/execute-fn + {:schema schema + :query {:as-id (->Identity nil (constantly true))} + :scalars {"ID" {:encode encode, :decode decode}}}) + result (is (execute! "{ asId(v: 10) }"))] + (is (= {"asId" nil} (:data result))) + (is (= "could not coerce value to 'ID': \"10\"" + (-> result :errors first :message)))))