Fork me on GitHub
#pathom
<
2022-05-16
>
roklenarcic11:05:04

I am trying out the error handling in Pathom 3 and I couldn’t get attribute-error function to return a non-nil result. I have a query by ident like [{[:user/id 1] [:user/name]}] and I’ve got the name resolver always throw an Excecption, and lenient mode on. I get what you’d expect:

{[:user/id 1] #:com.wsscode.pathom3.connect.runner{:attribute-errors #:user{:name #:com.wsscode.pathom3.error{:cause :com.wsscode.pathom3.error/node-errors,
                                                                                                                                      :node-error-details ......
But when I call (attribute-error response [:user/id 1]) I get back nil. I’ve looked at implementation of that function and subfunctions and it basicall uses com.wsscode.pathom3.connect.planner/index-attrs and com.wsscode.pathom3.connect.planner/index-ast and com.wsscode.pathom3.connect.runner/node-run-stats . And then I looked at my meta or response and saw that index-attrs was missing, and node-run-stats is empty map…. so of course this didn’t work. What am I doing wrong?

wilkerlucio13:05:49

the error is always per entity, and attribute error is about an attribute ,an ident query like [:user/id 1] will never have an error on itself because its just a data forward thing, the error will always be inside of it (meaning you need to look for the attribute error at that level), makes sense?

roklenarcic13:05:27

ok, so I need to request (attribute-error response :user/name)?

wilkerlucio13:05:55

more like: (attribute-error (get response [:user/id 1]) :user/name)]

roklenarcic13:05:29

the thing is that node-run-stats is empty and looking at the code it attribute-error it needs to have something in there

wilkerlucio13:05:08

note each map has its own meta with status details

wilkerlucio13:05:13

not just the root

roklenarcic13:05:24

So I’ll have to walk the result to log errors I think

wilkerlucio13:05:00

if you want to log errors, its better to use a plugin to wrap error events, its gonna be easier than traversing

roklenarcic13:05:14

Yeah I see that

wilkerlucio13:05:48

that said, traversing is possible, and that's what Pathom Viz does to compute the trace tree: https://github.com/wilkerlucio/pathom-viz/blob/master/src/core/com/wsscode/pathom/viz/timeline.cljs#L182-L230

wilkerlucio13:05:20

but for observability, an error plugin is easier and more efficient

roklenarcic14:05:22

Let’s say you’ve got a button, and it’s got ::button/shape resolver, which describes a “type” (e.g. either circle or a square), and the circle shape has radius, but the square has width, height as attributes, how would you write that resolver output?

(pco/defresolver button-shape [{::button/keys [id]}]
  {::pco/output [{::button/shape [::shape/type ::shape/radius ::shape/width ::shape/height]}]}
  {::button/shape
   (let [b (get-button id)]
     (if (= "circle" (:shape b))
       {::shape/type :circle ::shape/radius (:radius b)}
       {::shape/type :square ::shape/width (:width b) ::shape/height (:height b)}))})

cjmurphy15:05:01

You could have a separate resolver for each shape. So a resolver for circle/id and another for square/id. This way Pathom has a resolver (and a <table-name>/id) for each grouping of attributes. Of course I realise that's not answering the question so please take it as a comment.

roklenarcic16:05:27

How would that work? Union query?

cjmurphy16:05:51

I was suggesting that the schema be changed to accommodate Pathom, so no more types. That's just how I might go about it, given you only have 2 types, and there aren't even any attributes in common. I would have a circle resolver and a square resolver.

wilkerlucio19:05:18

I think your approach is fine, you could go with Unions to make it more specific but I dont think its nescessary (the add complexity of dealing with unions is not worth given the difference in attributes is so short)

roklenarcic19:05:21

But without unions I have problem where th resolver is in error because it is not returning all the requested properties

cjmurphy21:05:29

Well for those attributes you could return nil or your own key, say :not-needed. That would stop the error. But maybe there's a better way...

wilkerlucio22:05:37

you can also use optionality to handle the missing data cases, like:

(p.eql/process env [{::button/shape [::shape/type (pco/? ::shape/radius) (pco/? ::shape/width) (pco/? ::shape/height)]}
]

wilkerlucio22:05:04

or returning nils, as @U0D5RN0S1 mentioned

dehli22:05:59

Is it possible to get whether a :node-id is optional from within the runner? (or does that question not make sense 🙂). I'm looking through the source code and trying to address https://github.com/wilkerlucio/pathom3/issues/138. My thoughts are inside of pcr/run-or-node! after we've gone through all the nodes, if the key is optional, rather than failing fast we could continue w/ execution. Also hi! 👋

wilkerlucio23:05:32

just sent a possible fix, let me know if works in your scenario 🙂

wilkerlucio23:05:23

about the question o optional node, a optional node doesn't make sense, because the node might have both required and optional things to fulfill, the optionality is something we check at the index-ast via the attribute key (looking for the optional param there)

dehli23:05:38

Thanks! That looks like it would work for my scenario. I'll pull latest for my project. Thanks for answering the node question! That makes sense to me.

wilkerlucio23:05:59

currently every OR node can have only one attribute expected, but since this is a thing that's not used extensively (this may change in the future with better optimizations), I believe we still gonna find some rough edges, and fix as we find them 🙂

dehli00:05:03

Just confirmed that the fix worked for my more complicated example 🎉 Thanks for your help and explanation! And I'll happily continue to help surface any rough edges as I find them 🙂

🎉 1