-
Notifications
You must be signed in to change notification settings - Fork 115
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
base: main
Are you sure you want to change the base?
Conversation
…ass while deserializing rulebase
@@ -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 %)] |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 ;)
There was a problem hiding this 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 %)] |
There was a problem hiding this comment.
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?
Co-authored-by: Mike Rodriguez <mjr4184@gmail.com>
Co-authored-by: Mike Rodriguez <mjr4184@gmail.com>
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
corrected:
5252ca5
There was a problem hiding this comment.
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 %}))) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
corrected:
5252ca5
There was a problem hiding this 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: '" % "'") |
There was a problem hiding this comment.
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".
…rializing rulebase
#264