Skip to content

Commit 7793857

Browse files
fix runLayer safety for open rows
Prevent runLayer from accepting open requirement rows so missing dependencies fail at compile time instead of crashing at runtime. Add regression coverage for the bad case and preserve support for running closed-row layers with superset contexts.
1 parent c6ad2c1 commit 7793857

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-- EXPECT: Prim.RowList.RowToList
2+
module Yoga.Om.Layer.CompileFailTest where
3+
4+
import Prelude
5+
6+
import Yoga.Om as Om
7+
import Yoga.Om.Layer (OmLayer, makeLayer, runLayer)
8+
9+
type Fastify = String
10+
type Connection = String
11+
12+
apiLayer :: forall r. OmLayer (fastify :: Fastify, sqlite :: Connection | r) () {}
13+
apiLayer = makeLayer do
14+
{ fastify, sqlite } <- Om.ask
15+
let _ = fastify <> sqlite
16+
pure {}
17+
18+
bad :: Om.Om { fastify :: Fastify } () {}
19+
bad = runLayer { fastify: "server" } apiLayer

src/Yoga/Om/Layer.purs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,9 +340,13 @@ else instance
340340
-- =============================================================================
341341

342342
-- | Run a layer with a given context, with custom error if requirements aren't met.
343+
-- | `runLayer` requires a closed requirement row. If you have an open layer like
344+
-- | `OmLayer (db :: Db | r) err a`, specialize it to a closed row before running
345+
-- | it directly.
343346
runLayer
344347
:: forall req err a available
345348
. CheckAllProvided req available
349+
=> Keys req
346350
=> Record available
347351
-> OmLayer req err a
348352
-> Om (Record available) err a

test/Test/Yoga/Om/Layer/InstancesSpec.purs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ spec = do
4646
result <- Om.runOm {} { exception: \_ -> pure { result: 0 } } (runLayer {} layer)
4747
result.result `shouldEqual` 15
4848

49+
it "runs layers against a superset context" do
50+
let
51+
layer :: OmLayer (a :: Int) () { out :: Int }
52+
layer = makeLayer do
53+
{ a } <- Om.ask
54+
pure { out: a + 1 }
55+
56+
ctx = { a: 41, extra: "ok" }
57+
58+
result <- Om.runOm ctx { exception: \_ -> pure { out: 0 } } (runLayer ctx layer)
59+
result.out `shouldEqual` 42
60+
4961
describe "Parallel" do
5062

5163
it "runs layers in parallel via parApply" do

0 commit comments

Comments
 (0)