This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-31
Channels
- # aws (1)
- # beginners (70)
- # boot (12)
- # calva (45)
- # cider (45)
- # clara (1)
- # cljdoc (10)
- # cljs-dev (133)
- # clojure (315)
- # clojure-dev (2)
- # clojure-europe (2)
- # clojure-italy (16)
- # clojure-nl (1)
- # clojure-spec (23)
- # clojure-uk (19)
- # clojurescript (48)
- # cursive (11)
- # data-science (5)
- # datomic (18)
- # figwheel-main (3)
- # fulcro (18)
- # graphql (14)
- # jackdaw (1)
- # juxt (1)
- # kaocha (1)
- # off-topic (10)
- # other-languages (3)
- # pathom (2)
- # pedestal (7)
- # re-frame (23)
- # reagent (1)
- # reitit (4)
- # ring-swagger (12)
- # rum (4)
- # shadow-cljs (26)
- # specter (6)
- # speculative (12)
- # tools-deps (44)
- # vim (8)
- # yada (2)
oops, sorry, for an update I spent this morning trying to put together a simple example test case, having it not fail, and determining it was something stupid I did
We are making a GraphQL gateway and have got a bit stuck with async. If we use callbacks then it’s difficult to ensure correct error handling, but if we use some async abstraction library we’re stuck making a lot of adapters. I wondered how are other Lacinia users addressing this problem?
@cbowdon we use manifold in our resolvers and wrap each resolver in a function that turns a deferred into a lacinia promise. Manifold has a nice way of handling errors.
there used to be a thing called :decorators
in lacinia which i think would give you what you need. according to the changelog they were removed because they'd be more easily expressed in code
i don't know what the recommended approach might be now, unless you map over your resolver map and comp the resolver functions with your adapter stuff before attaching them
I've got a function that takes a core.async channel and returns something that satisfies the ResolverResult protocol, so the body of all my resolve functions starts like (f (go ...))
:thinking_face: what do you mean by "correct" error handling? What are the challenges you expect to encounter?
but exceptions also don't compose well with a lot of other coding styles, and the most common solution is to usually turn errors in to special return values and don't use exceptions
We often follow the pattern of conveying either a result or an exception through the channel, which complicates the code that takes the conveyed value ... sometimes a macro helps to sort that out. It also can cause problems if the channel is part of a pipeline that can be tripped up when a value in the channel isn't the expected map or vector.
We've got a middleware stack that wraps our resolvers. One of the middlewares is responsible for invoking the resolver in a claypoole future and returning a lacinia promise. Basically, it takes a synchronous resolver and returns an async one.
Another middleware (further "in" the stack) wraps the resolver in a try
/`catch` for exception handling.
The resolvers themselves do not have any sort of async code, so we don't experience any clashing between exception handling and async