diff --git a/src/cljc/mw_engine/core.clj b/src/cljc/mw_engine/core.clj
index ed7c48f..34e063b 100644
--- a/src/cljc/mw_engine/core.clj
+++ b/src/cljc/mw_engine/core.clj
@@ -58,7 +58,16 @@
   ;; of the rule function itself. Yes, I know, this is obvious; but I'll confess
   ;; I didn't think of it before.
   [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
       (merge result (meta rule)))))
 
@@ -66,7 +75,18 @@
   "Derive a cell from this `cell` of this `world` by applying these `rules`."
   [world cell rules]
   (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))
 
 (defn- transform-cell
@@ -78,17 +98,13 @@
      (apply-rules world cell rules)
      {:generation (+ (get-int-or-zero cell :generation) 1)})
     (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)
                               (.getMessage e)
                               (:generation cell)
                               (:state cell))]
         (l/warn e narrative)
-      (merge cell {:error narrative 
-                   :stacktrace ;; (remove #(starts-with? % "clojure.") 
-                                       (map #(.toString %) (.getStackTrace e))
-                               ;;)
-                   :state :error})))))
+        cell))))
 
 (defn transform-world
   "Return a world derived from this `world` by applying the production rules 
diff --git a/src/cljc/mw_engine/utils.clj b/src/cljc/mw_engine/utils.clj
index c7e070b..684064e 100644
--- a/src/cljc/mw_engine/utils.clj
+++ b/src/cljc/mw_engine/utils.clj
@@ -138,16 +138,16 @@
             :else 0))
     (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
    present (or not a number) return 0.
 
   * `map` a map;
   * `key` a symbol or keyword, presumed to be a key into the `map`."
   [map key]
-  (if (map? map)
-    (let [v (map key)]
-      (cond (and v (number? v)) v
+  `(if (map? ~map)
+    (let [~'v (~map ~key)]
+      (cond (and ~'v (number? ~'v)) ~'v
             :else 0))
     (throw (Exception. "No map passed?"))))
 
diff --git a/test/mw_engine/core_test.clj b/test/mw_engine/core_test.clj
index 57a3d65..f6c056d 100644
--- a/test/mw_engine/core_test.clj
+++ b/test/mw_engine/core_test.clj
@@ -11,19 +11,13 @@
                  (cond
                    (= (:state cell) :new)
                    (merge cell {:state :grassland}))))
-               merge {:rule-type :production})
-          pair (list afn "Test source")]
+               merge {:rule-type :production
+                      :rule "Test source"})]
       (is (nil? (apply-rule nil {:state :water} afn))
           "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)
-          "Rule should fire when state is correct")
-      (is (= (:state (apply-rule nil {:state :new} pair)) :grassland)
-          "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 should fire when state is correct") 
+      (is (= (:rule (apply-rule nil {:state :new} afn)) "Test source")
           "Rule text cached on cell if provided"))))
 
 (deftest transform-world-tests
@@ -34,10 +28,11 @@
                   (cond
                     (= (:state cell) :new)
                     (merge cell {:state :grassland}))))
-               merge {:rule-type :production})
+               merge {:rule-type :production
+                      :rule "Test source"})
           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}] 
-                    [{: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 2, :state :grassland, :x 0, :generation 1} {:y 2, :state :grassland, :x 1, :generation 1} {:y 2, :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, :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, :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))]
       (is (= actual expected)))))
\ No newline at end of file