More logging, more sophisticated massage-params, do-or-log-error

This commit is contained in:
Simon Brooke 2018-07-02 10:58:18 +01:00
parent 8e5c756e0d
commit a855554ed8
3 changed files with 64 additions and 16 deletions

View file

@ -5,4 +5,5 @@
:url "https://opensource.org/licenses/MIT"}
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/math.numeric-tower "0.0.4"]
[org.clojure/tools.logging "0.3.1"]
[selmer "1.10.6"]])

View file

@ -42,30 +42,46 @@
(split query-string #"\&")))))
(defn massage-value
[k m]
(let [v (m k)
vr (if
(string? v)
(try
(read-string v)
(catch Exception _ nil)))]
(cond
(nil? v) {}
(= v "") {}
(number? vr) {k vr}
true
{k v})))
(defn massage-params
"Sending empty strings, or numbers as strings, to the database often isn't
helpful. Massage these `params` to eliminate these problems."
[params]
helpful. Massage these `params` and `form-params` to eliminate these problems.
We must take key field values out of just params, but we should take all other
values out of form-params - because we need the key to load the form in
the first place, but just accepting values of other params would allow spoofing."
[params form-params key-fields]
(reduce
merge
;; do the keyfields first, from params
(reduce
merge
{}
(map
(fn [k]
(let [v (params k)
vr (if
(string? v)
(try
(read-string v)
(catch Exception _ nil)))]
(cond
(nil? v) {}
(= v "") {}
(number? vr) {k vr}
true
{k v})))
#(massage-value % params)
(filter
#(key-fields (str (name %)))
(keys params))))
;; then merge in everything from form-params, potentially overriding what
;; we got from params.
(map
#(massage-value % form-params)
(keys form-params))))
(massage-params {:a "a" :b "1" :c nil})
(defn
raw-resolve-template
@ -75,5 +91,25 @@
n
(str "auto/" n)))
(def resolve-template (memoize raw-resolve-template))
(defmacro do-or-log-error
"Evaluate the supplied `form` in a try/catch block. If the
keyword param `:message` is supplied, the value will be used
as the log message; if the keyword param `:error-return` is
supplied, the value will be returned if an exception is caught."
[form & {:keys [message error-return]
:or {message `(str "A failure occurred in "
~(list 'quote form))}}]
`(try
~form
(catch Exception any#
(clojure.tools.logging/error
(str ~message
(with-out-str
(-> any# .printStackTrace))))
~error-return)))

View file

@ -4,6 +4,7 @@
(:require [clojure.math.numeric-tower :refer [expt]]
[clojure.pprint :as p]
[clojure.string :as s]
[clojure.tools.logging :as log]
[clojure.xml :as x]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -22,6 +23,7 @@
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; TODO: this really ought to be split into several namespaces
(def ^:dynamic *locale*
"The locale for which files will be generated."
@ -343,6 +345,15 @@
(filter #(#{"user" "all"} (:distinct (:attrs %))) (all-properties entity)))
(defn user-distinct-property-names
"Return, as a set, the names of properties which are user distinct"
[entity]
(set
(map
(fn [x] (-> x :attrs :name))
(user-distinct-properties entity))))
(defmacro insertable-properties
"Return all the properties of this `entity` (including key properties) into
which user-supplied data can be inserted"