Much better error logging on rule execution.
This commit is contained in:
parent
ac25969f90
commit
85d66208b9
|
@ -58,7 +58,16 @@
|
||||||
;; of the rule function itself. Yes, I know, this is obvious; but I'll confess
|
;; of the rule function itself. Yes, I know, this is obvious; but I'll confess
|
||||||
;; I didn't think of it before.
|
;; I didn't think of it before.
|
||||||
[world cell rule]
|
[world cell rule]
|
||||||
(let [result (apply rule (list cell world))]
|
(let [result (try
|
||||||
|
(apply rule (list cell world))
|
||||||
|
(catch Exception e
|
||||||
|
(l/warn e
|
||||||
|
(format
|
||||||
|
"Error in `apply-rule`: `%s` (%s) while executing rule `%s` on cell `%s`"
|
||||||
|
e
|
||||||
|
(.getMessage e)
|
||||||
|
(-> rule meta :lisp)
|
||||||
|
cell))))]
|
||||||
(when result
|
(when result
|
||||||
(merge result (meta rule)))))
|
(merge result (meta rule)))))
|
||||||
|
|
||||||
|
@ -66,7 +75,18 @@
|
||||||
"Derive a cell from this `cell` of this `world` by applying these `rules`."
|
"Derive a cell from this `cell` of this `world` by applying these `rules`."
|
||||||
[world cell rules]
|
[world cell rules]
|
||||||
(or
|
(or
|
||||||
(first (remove nil? (map #(apply-rule world cell %) rules)))
|
(first
|
||||||
|
(remove
|
||||||
|
nil?
|
||||||
|
(try
|
||||||
|
(map #(apply-rule world cell %) rules)
|
||||||
|
(catch Exception e
|
||||||
|
(l/warn e
|
||||||
|
(format
|
||||||
|
"Error in `apply-rules`: `%s` (%s) while executing rules on cell `%s`"
|
||||||
|
e
|
||||||
|
(.getMessage e)
|
||||||
|
cell))))))
|
||||||
cell))
|
cell))
|
||||||
|
|
||||||
(defn- transform-cell
|
(defn- transform-cell
|
||||||
|
@ -78,17 +98,13 @@
|
||||||
(apply-rules world cell rules)
|
(apply-rules world cell rules)
|
||||||
{:generation (+ (get-int-or-zero cell :generation) 1)})
|
{:generation (+ (get-int-or-zero cell :generation) 1)})
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(let [narrative (format "%s with message `%s` at generation %d when in state %s"
|
(let [narrative (format "Error in `transform-cell`: `%s` (%s) at generation %d when in state %s;"
|
||||||
(-> e .getClass .getName)
|
(-> e .getClass .getName)
|
||||||
(.getMessage e)
|
(.getMessage e)
|
||||||
(:generation cell)
|
(:generation cell)
|
||||||
(:state cell))]
|
(:state cell))]
|
||||||
(l/warn e narrative)
|
(l/warn e narrative)
|
||||||
(merge cell {:error narrative
|
cell))))
|
||||||
:stacktrace ;; (remove #(starts-with? % "clojure.")
|
|
||||||
(map #(.toString %) (.getStackTrace e))
|
|
||||||
;;)
|
|
||||||
:state :error})))))
|
|
||||||
|
|
||||||
(defn transform-world
|
(defn transform-world
|
||||||
"Return a world derived from this `world` by applying the production rules
|
"Return a world derived from this `world` by applying the production rules
|
||||||
|
|
|
@ -138,16 +138,16 @@
|
||||||
:else 0))
|
:else 0))
|
||||||
(throw (Exception. "No map passed?"))))
|
(throw (Exception. "No map passed?"))))
|
||||||
|
|
||||||
(defn get-num
|
(defmacro get-num
|
||||||
"Get the value of a property expected to be a number from a map; if not
|
"Get the value of a property expected to be a number from a map; if not
|
||||||
present (or not a number) return 0.
|
present (or not a number) return 0.
|
||||||
|
|
||||||
* `map` a map;
|
* `map` a map;
|
||||||
* `key` a symbol or keyword, presumed to be a key into the `map`."
|
* `key` a symbol or keyword, presumed to be a key into the `map`."
|
||||||
[map key]
|
[map key]
|
||||||
(if (map? map)
|
`(if (map? ~map)
|
||||||
(let [v (map key)]
|
(let [~'v (~map ~key)]
|
||||||
(cond (and v (number? v)) v
|
(cond (and ~'v (number? ~'v)) ~'v
|
||||||
:else 0))
|
:else 0))
|
||||||
(throw (Exception. "No map passed?"))))
|
(throw (Exception. "No map passed?"))))
|
||||||
|
|
||||||
|
|
|
@ -11,19 +11,13 @@
|
||||||
(cond
|
(cond
|
||||||
(= (:state cell) :new)
|
(= (:state cell) :new)
|
||||||
(merge cell {:state :grassland}))))
|
(merge cell {:state :grassland}))))
|
||||||
merge {:rule-type :production})
|
merge {:rule-type :production
|
||||||
pair (list afn "Test source")]
|
:rule "Test source"})]
|
||||||
(is (nil? (apply-rule nil {:state :water} afn))
|
(is (nil? (apply-rule nil {:state :water} afn))
|
||||||
"Rule shouldn't fire when state is wrong")
|
"Rule shouldn't fire when state is wrong")
|
||||||
(is (nil? (apply-rule nil {:state :water} pair))
|
|
||||||
"Rule shouldn't fire when state is wrong")
|
|
||||||
(is (= (:state (apply-rule nil {:state :new} afn)) :grassland)
|
(is (= (:state (apply-rule nil {:state :new} afn)) :grassland)
|
||||||
"Rule should fire when state is correct")
|
"Rule should fire when state is correct")
|
||||||
(is (= (:state (apply-rule nil {:state :new} pair)) :grassland)
|
(is (= (:rule (apply-rule nil {:state :new} afn)) "Test source")
|
||||||
"Rule should fire when state is correct")
|
|
||||||
(is (nil? (:rule (apply-rule nil {:state :new} afn)))
|
|
||||||
"No rule text if not provided")
|
|
||||||
(is (= (:rule (apply-rule nil {:state :new} pair)) "Test source")
|
|
||||||
"Rule text cached on cell if provided"))))
|
"Rule text cached on cell if provided"))))
|
||||||
|
|
||||||
(deftest transform-world-tests
|
(deftest transform-world-tests
|
||||||
|
@ -34,10 +28,11 @@
|
||||||
(cond
|
(cond
|
||||||
(= (:state cell) :new)
|
(= (:state cell) :new)
|
||||||
(merge cell {:state :grassland}))))
|
(merge cell {:state :grassland}))))
|
||||||
merge {:rule-type :production})
|
merge {:rule-type :production
|
||||||
|
:rule "Test source"})
|
||||||
world (make-world 3 3)
|
world (make-world 3 3)
|
||||||
expected [[{:y 0, :state :grassland, :x 0, :generation 1} {:y 0, :state :grassland, :x 1, :generation 1} {:y 0, :state :grassland, :x 2, :generation 1}]
|
expected [[[{:y 0, :state :grassland, :x 0, :rule-type :production, :rule "Test source", :generation 1} {:y 0, :state :grassland, :x 1, :rule-type :production, :rule "Test source", :generation 1} {:y 0, :state :grassland, :x 2, :rule-type :production, :rule "Test source", :generation 1}]
|
||||||
[{:y 1, :state :grassland, :x 0, :generation 1} {:y 1, :state :grassland, :x 1, :generation 1} {:y 1, :state :grassland, :x 2, :generation 1}]
|
[{:y 1, :state :grassland, :x 0, :rule-type :production, :rule "Test source", :generation 1} {:y 1, :state :grassland, :x 1, :rule-type :production, :rule "Test source", :generation 1} {:y 1, :state :grassland, :x 2, :rule-type :production, :rule "Test source", :generation 1}]
|
||||||
[{:y 2, :state :grassland, :x 0, :generation 1} {:y 2, :state :grassland, :x 1, :generation 1} {:y 2, :state :grassland, :x 2, :generation 1}]]
|
[{:y 2, :state :grassland, :x 0, :rule-type :production, :rule "Test source", :generation 1} {:y 2, :state :grassland, :x 1, :rule-type :production, :rule "Test source", :generation 1} {:y 2, :state :grassland, :x 2, :rule-type :production, :rule "Test source", :generation 1}]]]
|
||||||
actual (transform-world world (list afn))]
|
actual (transform-world world (list afn))]
|
||||||
(is (= actual expected)))))
|
(is (= actual expected)))))
|
Loading…
Reference in a new issue