Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#264:Provide better exception when unable to resolve class while dese… #476

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

EthanEChristian
Copy link
Contributor

…rializing rulebase

#264

@@ -132,7 +132,11 @@
([^Reader rdr]
(read-record rdr nil))
([^Reader rdr add-fn]
(let [builder (-> (.readObject rdr) resolve deref)
(let [try-resolve #(if-let [clazz (resolve %)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be named resolve-or-fail

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s used elsewhere I think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not in this repo, but it is around ;)

Copy link
Collaborator

@mrrodriguez mrrodriguez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have minor suggestions.

@@ -132,7 +132,11 @@
([^Reader rdr]
(read-record rdr nil))
([^Reader rdr add-fn]
(let [builder (-> (.readObject rdr) resolve deref)
(let [try-resolve #(if-let [clazz (resolve %)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s used elsewhere I think?

src/main/clojure/clara/rules/durability/fressian.clj Outdated Show resolved Hide resolved
src/main/clojure/clara/rules/durability/fressian.clj Outdated Show resolved Hide resolved
EthanEChristian and others added 2 commits July 21, 2022 08:00
Co-authored-by: Mike Rodriguez <mjr4184@gmail.com>
Co-authored-by: Mike Rodriguez <mjr4184@gmail.com>
mrrodriguez
mrrodriguez previously approved these changes Jul 21, 2022
@EthanEChristian
Copy link
Contributor Author

I plan on merging this this weekend to allow for a little additional time for @WilliamParker if he is able to.

@@ -132,7 +132,11 @@
([^Reader rdr]
(read-record rdr nil))
([^Reader rdr add-fn]
(let [builder (-> (.readObject rdr) resolve deref)
(let [try-resolve #(if-let [clazz (resolve %)]
clazz
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is a class, but rather a Clojure Var for the record constructor function. From the implementation before this PR:

(defn write-record
  "Same as write-with-meta, but with Clojure record support.  The type of the record will
   be preserved."
  [^Writer w tag rec]
  (let [m (meta rec)]
    (.writeTag w tag 3)
    (.writeObject w (record-map-constructor-name rec) true)
    (write-map w rec)
    (if m
      (.writeObject w m)
      (.writeNull w))))

Then looking at the current read implementation:

(defn read-record
  "Same as read-with-meta, but with Clojure record support.  The type of the record will
   be preserved."
  ([^Reader rdr]
   (read-record rdr nil))
  ([^Reader rdr add-fn]
   (let [builder (-> (.readObject rdr) resolve deref)
         build-map (.readObject rdr)
         m (read-meta rdr)]
     (cond-> (builder build-map)
       m (with-meta m)
       add-fn add-fn))))

If the resolved value was a class it wouldn't be possible to invoke it as a Clojure function - note the (builder build-map) call.

Assuming I'm not missing something, this makes testing easier if you're so inclined, though for this sort of error handling I don't think it is critical. You could just use ns-unmap before deserializing.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point. So the suggestion (besides testing) is that the resolved symbol isn't a class at all and the message should avoid being worded suggesting that it is. Also, we shouldn't call it clazz, but perhaps just resolved or resolved-var or something like that? It is notable that deref is called on it a step later, so it definition can't be a class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected:
5252ca5

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo:
add a test

(let [try-resolve #(if-let [clazz (resolve %)]
clazz
(throw (ex-info (str "Unable to resolve fact type symbol: '" % "'")
{:fact-type-class %})))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is specific to facts? It is being used for all Clojure records from what I can see here (admittedly it has been a while since I read through this): https://github.com/cerner/clara-rules/blob/0.21.2/src/main/clojure/clara/rules/durability/fressian.clj#L386

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are right. It really is a failure to resolve a record builder fn.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected:
5252ca5

Copy link
Contributor Author

@EthanEChristian EthanEChristian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct terminology

(let [builder (-> (.readObject rdr) resolve deref)
(let [try-resolve #(if-let [resolved (resolve %)]
resolved
(throw (ex-info (str "Unable to resolve fact type symbol: '" % "'")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is necessarily a fact, although if the Fressian handlers are being brought in by an IWorkingMemorySerializer implementation they usually will be - the Clara engine nodes have their own handlers anyway: https://github.com/cerner/clara-rules/blob/0.21.2/src/main/clojure/clara/rules/durability/fressian.clj#L393 So this seems OK either way as "fact type symbol" or "record constructor symbol".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants