Codebase list kitchensink-clojure / a02eee9
(MAINT) change error format, bump to 2.0.0 This commit changes the kitchensink slingshot error maps to use the format that is more commonly used in the other PL clojure projects, replacing `:type` and `:message` with `:kind` and `:msg`. It also bumps the version number up to 2.0.0, because, technically, this is an API-breaking change :/ Chris Price 7 years ago
3 changed file(s) with 57 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
0 (defproject puppetlabs/kitchensink "1.4.1-SNAPSHOT"
0 (defproject puppetlabs/kitchensink "2.0.0-SNAPSHOT"
11 :description "Clojure utility functions"
22 :license {:name "Apache License, Version 2.0"
33 :url "http://www.apache.org/licenses/LICENSE-2.0.html"}
2424 [clj-time.coerce :only [ICoerce to-date-time]]
2525 [clj-time.format :only [formatters unparse]]))
2626
27
28 (defn error-map
29 [kind message]
30 {:kind kind
31 :msg message})
32
2733 ;; ## Type checking
2834
2935 (defn array?
6975 (condp = (.toLowerCase s)
7076 "true" true
7177 "false" false
72 (throw+ {:type ::parse-error
73 :message (format "Unable to parse '%s' to a boolean" s)})))
78 (throw+ (error-map ::parse-error
79 (format "Unable to parse '%s' to a boolean" s)))))
7480
7581 (defn parse-bool
7682 "Parse a string and return its boolean value."
161167
162168 The slingshot exception will look like this:
163169
164 `{:type :puppetlabs.kitchensink.core/io-error
165 :message \"Parent directory '/foo/bar' is not writable\"}`"
170 `{:kind :puppetlabs.kitchensink.core/io-error
171 :msg \"Parent directory '/foo/bar' is not writable\"}`"
166172 [path]
167173 {:pre [((some-fn #(instance? File %) string?) path)]
168174 :post [(fs/directory? path)]}
169175 (let [path-as-file (fs/file path)]
170176 (if (fs/file? path-as-file)
171 (throw+ {:type ::io-error
172 :message (format "Path '%s' is a file" path)})
177 (throw+ (error-map ::io-error
178 (format "Path '%s' is a file" path)))
173179 (doseq [^File dir (reverse (cons path-as-file (fs/parents path-as-file)))]
174180 (when-not (fs/exists? dir)
175181 (let [parent (.getParentFile dir)]
176182 (when (fs/file? parent)
177 (throw+ {:type ::io-error
178 :message (format "Parent directory '%s' is a file"
179 parent)}))
183 (throw+ (error-map ::io-error
184 (format "Parent directory '%s' is a file"
185 parent))))
180186
181187 (when-not (.canWrite parent)
182 (throw+ {:type ::io-error
183 :message (format "Parent directory '%s' is not writable"
184 parent)}))
188 (throw+ (error-map ::io-error
189 (format "Parent directory '%s' is not writable"
190 parent))))
185191
186192 (let [success (.mkdir dir)]
187193 (when-not success
188 (throw+ {:type ::io-error
189 :message (format "Unable to create directory '%s'"
190 parent)})))))))))
194 (throw+ (error-map ::io-error
195 (format "Unable to create directory '%s'"
196 parent)))))))))))
191197
192198 ;; ## Math
193199
804810 the program to exit and display the help message.
805811
806812 ** The map is thrown using 'slingshot' (https://github.com/scgilardi/slingshot).
807 It contains a `:type` and `:message`, where type is either `:error` or `:help`,
813 It contains a `:kind` and `:msg`, where type is either `:error` or `:help`,
808814 and the message is either the error message or a help banner.
809815
810816 Returns a three-item vector, containing:
824830 (apply str errors)
825831 "\n\n"
826832 summary)]
827 (throw+ {:type ::cli-error
828 :message msg})))
833 (throw+ (error-map ::cli-error msg))))
829834 (when (:help options)
830 (throw+ {:type ::cli-help
831 :message summary}))
835 (throw+ (error-map ::cli-help summary)))
832836 (when-let [missing-field (some #(if (not (contains? options %)) %) required-args)]
833837 (let [msg (str
834838 "\n\n"
835839 (format "Missing required argument '--%s'!" (name missing-field))
836840 "\n\n"
837841 summary)]
838 (throw+ {:type ::cli-error
839 :message msg})))
842 (throw+ (error-map ::cli-error msg))))
840843 [options arguments summary])))
841844
842845
8080 (to-bool "hi")
8181 (is (not true) "Expected exception to be thrown by to-bool when an invalid string is passed")
8282 (catch map? m
83 (is (contains? m :type))
84 (is (= :puppetlabs.kitchensink.core/parse-error (:type m)))
85 (is (= :parse-error (without-ns (:type m))))
86 (is (contains? m :message))
87 (is (re-find #"Unable to parse 'hi' to a boolean" (:message m)))))))
83 (is (contains? m :kind))
84 (is (= :puppetlabs.kitchensink.core/parse-error (:kind m)))
85 (is (= :parse-error (without-ns (:kind m))))
86 (is (contains? m :msg))
87 (is (re-find #"Unable to parse 'hi' to a boolean" (:msg m)))))))
8888
8989 (deftest test-true-str?
9090 (are [t-or-f? str-val] (t-or-f? (true-str? str-val))
124124 (mkdirs! (fs/file tmpdir "foo" "bar" "baz"))
125125 (is (not true) "Expected exception to be thrown by mkdirs! when one of the elements of the path already exists and is a file")
126126 (catch map? m
127 (is (contains? m :type))
128 (is (= :puppetlabs.kitchensink.core/io-error (:type m)))
129 (is (= :io-error (without-ns (:type m))))
130 (is (contains? m :message))
131 (is (re-find #"foo/bar' is a file" (:message m)))))))
127 (is (contains? m :kind))
128 (is (= :puppetlabs.kitchensink.core/io-error (:kind m)))
129 (is (= :io-error (without-ns (:kind m))))
130 (is (contains? m :msg))
131 (is (re-find #"foo/bar' is a file" (:msg m)))))))
132132 (testing "throws exception if the path exists and is a file"
133133 (let [tmpdir (temp-dir)]
134134 (fs/mkdirs (fs/file tmpdir "foo"))
138138 (is (not true) (str "Expected exception to be thrown by mkdirs! when "
139139 "the path already exists and is a file"))
140140 (catch map? m
141 (is (contains? m :type))
142 (is (= :puppetlabs.kitchensink.core/io-error (:type m)))
143 (is (= :io-error (without-ns (:type m))))
144 (is (contains? m :message))
145 (is (re-find #"foo/bar' is a file" (:message m)))))))
141 (is (contains? m :kind))
142 (is (= :puppetlabs.kitchensink.core/io-error (:kind m)))
143 (is (= :io-error (without-ns (:kind m))))
144 (is (contains? m :msg))
145 (is (re-find #"foo/bar' is a file" (:msg m)))))))
146146 (testing "Permission denied on some directory in the hierarchy"
147147 (let [tmpdir (temp-dir)]
148148 (fs/mkdirs (fs/file tmpdir "foo"))
151151 (mkdirs! (fs/file tmpdir "foo" "bar" "baz"))
152152 (is (not true) "Expected exception to be thrown by mkdirs! when a permissions error occurs")
153153 (catch map? m
154 (is (contains? m :type))
155 (is (= :puppetlabs.kitchensink.core/io-error (:type m)))
156 (is (= :io-error (without-ns (:type m))))
157 (is (contains? m :message))
158 (is (re-find #"foo' is not writable" (:message m))))))))
154 (is (contains? m :kind))
155 (is (= :puppetlabs.kitchensink.core/io-error (:kind m)))
156 (is (= :io-error (without-ns (:kind m))))
157 (is (contains? m :msg))
158 (is (re-find #"foo' is not writable" (:msg m))))))))
159159
160160 (deftest quotient-test
161161 (testing "quotient"
466466 (try+
467467 (cli! [] [["-r" "--required" "A required field"]] [:required])
468468 (catch map? m
469 (is (contains? m :type))
470 (is (= :puppetlabs.kitchensink.core/cli-error (:type m)))
471 (is (= :cli-error (without-ns (:type m))))
472 (is (contains? m :message))
469 (is (contains? m :kind))
470 (is (= :puppetlabs.kitchensink.core/cli-error (:kind m)))
471 (is (= :cli-error (without-ns (:kind m))))
472 (is (contains? m :msg))
473473 (reset! got-expected-error true)))
474474 (is (true? @got-expected-error))))
475475
478478 (try+
479479 (cli! ["--help"] [] [])
480480 (catch map? m
481 (is (contains? m :type))
482 (is (= :puppetlabs.kitchensink.core/cli-help (:type m)))
483 (is (= :cli-help (without-ns (:type m))))
484 (is (contains? m :message))
481 (is (contains? m :kind))
482 (is (= :puppetlabs.kitchensink.core/cli-help (:kind m)))
483 (is (= :cli-help (without-ns (:kind m))))
484 (is (contains? m :msg))
485485 (reset! got-expected-help true)))
486486 (is (true? @got-expected-help))))
487487
509509 args ["--bar"]]
510510 (cli! args specs))
511511 (catch map? m
512 (is (= :puppetlabs.kitchensink.core/cli-error (:type m)))
513 (is (contains? m :message))
512 (is (= :puppetlabs.kitchensink.core/cli-error (:kind m)))
513 (is (contains? m :msg))
514514 (is (re-find
515515 #"Unknown option.*--bar"
516 (m :message)))
516 (m :msg)))
517517 (reset! got-expected-exception true)))
518518 (is (true? @got-expected-exception)))))
519519