   ([{::keys [data-bank] :as env}
     {::p.connect/keys [sym] :as resolver}
     input]
+   (print-trace env "call resolver" (pr-str sym) (pr-str input))
    (let [f (resolve sym)]
      (let [out (try
                  (some-> (f env input)
                          (dissoc ::p.connect/env))
                  (catch Throwable e
-                   e))]
+                   {::error e}))]
        (swap! data-bank update-in [::call-history sym] assoc input out)
        (log! env resolver {:in input :out out})
-       (if (map? out)
+       (if-not (::error out)
          (swap! data-bank bank-add out)))
      env)))
 

  "Mark attribute k as unreachable on db. Returns ::unreachable."
  [{::keys [data-bank]} k]
  (swap! data-bank update ::unreachable (fnil conj #{}) k)
  ::unreachable)

(defn seek-attr
  "Try to run more resolvers to get more attributes of type `attr`."
  [{::keys           [data-bank resolver-trace]
    ::p.connect/keys [indexes]
    :as              env}
   attr]
  (let [db      @data-bank
        db-keys (set (keys db))
        {::p.connect/keys [index-oir index-resolvers]} indexes]
    (if-let [attr-resolvers (get index-oir attr)]
      (if-let [attr-set (->> attr-resolvers
                             (mapcat (fn [[attrs syms]]
                                       (let [missing (set/difference attrs db-keys)]
                                         (for [s syms]
                                           {:sym     s
                                            :data    (get index-resolvers s)
                                            :attrs   attrs
                                            :missing missing}))))
                             (sort-by (comp count :missing))
                             (eduction
                               (remove (comp (or resolver-trace #{}) :sym))
                               (keep (fn [{:keys [sym data]}]
                                       (if (and (test-resolver (update env ::resolver-trace (fnil conj #{}) sym) data)
                                                (not= (get db attr) (get @data-bank attr)))
                                         (get @data-bank attr)))))
                             (first))]
        attr-set
        (unreachable env attr))
      (unreachable env attr))))

(defn resolve-attr
  "Find a value for an attribute."

  (let [db @data-bank]
    (or (get db attr)
        (if (contains? (::unreachable db) attr)
          {::error ::unreachable}
          (seek-attr env attr)))))

(defn discover-data
