diff --git a/src/huff2/core.clj b/src/huff2/core.clj index 4e3727e..96b4bbd 100644 --- a/src/huff2/core.clj +++ b/src/huff2/core.clj @@ -118,6 +118,16 @@ (defmulti emit (fn [_append! form _opts] (:key form))) +(defmethod emit :default [_append! form _opts] + (throw (ex-info (cond + (keyword? (:value form)) + (str "Got a bare keyword " (:value form) + " — wrap it in a vector to make an HTML element, e.g. [" + (:value form) "]") + :else + (str "Unexpected hiccup form: " (pr-str form))) + {:form form}))) + (defmethod emit :primative [append! {:keys [value]} _opts] (maybe-escape-html append! value)) @@ -258,7 +268,14 @@ (emit append! c opts))) (defmethod emit :component-node [append! {{{:keys [view-fxn children]} :values} :value} {:keys [parser] :as opts}] - (emit append! (parser (apply view-fxn children)) opts)) + (let [result (apply view-fxn children) + parsed (parser result)] + (if (= parsed :malli.core/invalid) + (throw (ex-info (str "Component " view-fxn " returned invalid hiccup") + {:component view-fxn + :args children + :returned result})) + (emit append! parsed opts)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Public api diff --git a/test/huff/core2_test.clj b/test/huff/core2_test.clj index b6a1cc1..1445137 100644 --- a/test/huff/core2_test.clj +++ b/test/huff/core2_test.clj @@ -1,7 +1,7 @@ (ns huff.core2-test (:require [huff2.core :as h] [clojure.string :as str] - [clojure.test :refer [deftest is]])) + [clojure.test :refer [deftest is testing]])) (deftest class-list-equality-test (is (= (h/html [:div]) (h/html [:div]))) @@ -180,3 +180,14 @@ (str (h/html [:div {:style {:width (-> 10 h/vmin)}}])))) (is (= "
" (str (h/html [:div {:style {:width (-> 10 h/vmax)}}]))))) + +(deftest component-invalid-hiccup-error-test + (testing "component returning invalid hiccup gives clear error" + (let [bad-component (fn [] :div)] + (is (thrown-with-msg? Exception #"returned invalid hiccup" + (h/html [:div [bad-component]]))))) + (testing "component returning bare keyword mentions the component" + (let [bad-component (fn [] :div) + ex-data' (try (h/html [:div [bad-component]]) + (catch Exception e (ex-data e)))] + (is (= :div (:returned ex-data'))))))