Skip to content

Query with mismatched data lead to DataError-Related nth Exception #82

@JackSho

Description

@JackSho

Problem

If I provide a wrongly named query or the function returns the wrong data that doesn't match, I will get a DataError in sub query when querying, and DataError will be passed to this line, then trigger an exception nth not supported on this type: DataError.

Because we unstruct the arg inline, but DataError record can not be unstructed.

;; normal
((query '{(:a :with [10]) [{:val ?}]})
 {:a (fn [n]
       [{:n n :val (inc n)}
        {:n n :val (dec n)}])})
;;=> {&? {:a [{:val 11} {:val 9}]}}

;; vector query not match the single map
((query '{(:a :with [10]) [{:val ?}]})
 {:a (fn [n]
       {:n n :e-val (inc n)})})
;;throws=>> #:error{:class java.lang.UnsupportedOperationException, :message "nth not supported on this type: DataError"}

Suggestion

  1. Callers will be confused when getting UnsupportedOperationException exception, the real exception expect sequential data is covered. Callers should know the first error expect sequential data, it is real and helpful.
  2. Modify the fn named-query-factory, don't use inline unstructuring, and check if it is DataError before unstructuring.
(defn named-query-factory
  "returns a new NamedQueryFactory
   - `a-symbol-table`: an atom of map to accept symbol-> val pair"
  ([]
   (named-query-factory (transient {})))
  ([symbol-table]
   (let [set-val! (fn [sym v] (get (assoc! symbol-table sym v) sym))]
     (context-of
      (fn [[sym] pair-or-error]
        ;; pair-or-error can be a DataError. If it is, unstructuring it will trigger a new nth exception.
        (if (error? pair-or-error)
          [nil (into {} pair-or-error)]
          (let [[k v :as pair] pair-or-error]
            ... 
            ;; no modification
            ...
            )))
      #(into % (filter (fn [[_ v]] (not= ::invalid v))) (persistent! symbol-table))))))
;; vector query not match the single map
((query '{(:a :with [10]) [{:val ?}]})
 {:a (fn [n]
       {:n n :e-val (inc n)})})
;;=> {&? {:a {:data {:n 10, :e-val 11}, :query-id (:val), :reason "expect sequential data"}}}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions