git.iko.soy/rowtype-yoga/purescript-yoga-http-api
on feat/custom-type-errors help sign in
feat: Add custom type error for invalid response record structure
5dab988Mark
src/Yoga/HTTP/API/Path.purs+1−1
@@ -34,7 +34,6 @@ import Prim.Row as Row
34import Record as Record
34import Record as Record
35import Type.Proxy (Proxy(..))
35import Type.Proxy (Proxy(..))
36import Unsafe.Coerce (unsafeCoerce)
36import Unsafe.Coerce (unsafeCoerce)
37−
38--------------------------------------------------------------------------------
37--------------------------------------------------------------------------------
39-- Type-Level Path DSL
38-- Type-Level Path DSL
40--------------------------------------------------------------------------------
39--------------------------------------------------------------------------------
@@ -242,6 +241,7 @@ instance parseParamNumber :: ParseParam Number where
242 Nothing -> Left $ "Expected a number but got: " <> s
241 Nothing -> Left $ "Expected a number but got: " <> s
243 Just n -> Right (Int.toNumber n) -- Simple version, doesn't handle floats
242 Just n -> Right (Int.toNumber n) -- Simple version, doesn't handle floats
244
243
244+
245-- | Parse a URL string into a record of typed path parameters
245-- | Parse a URL string into a record of typed path parameters
246-- |
246-- |
247-- | Examples:
247-- | Examples:
src/Yoga/HTTP/API/Route/Response.purs+38
@@ -19,6 +19,7 @@ import Data.Variant (Variant)
19import Data.Variant as Variant
19import Data.Variant as Variant
20import Prim.Row (class Cons)
20import Prim.Row (class Cons)
21import Prim.RowList as RL
21import Prim.RowList as RL
22+import Prim.TypeError (class Fail, Text, Above)
22import Type.Proxy (Proxy(..))
23import Type.Proxy (Proxy(..))
23import Unsafe.Coerce (unsafeCoerce)
24import Unsafe.Coerce (unsafeCoerce)
24
25
@@ -70,6 +71,43 @@ instance toResponseRLBodyHeaders ::
70else instance toResponseRLBodyOnly ::
71else instance toResponseRLBodyOnly ::
71 ToResponseRL (RL.Cons "body" body RL.Nil) () body
72 ToResponseRL (RL.Cons "body" body RL.Nil) () body
72
73
74+-- Invalid record structure: has fields other than "body" and "headers"
75+else instance toResponseRLInvalid ::
76+ ( Fail
77+ ( Above
78+ (Text "Invalid response record structure.")
79+ ( Above
80+ (Text "")
81+ ( Above
82+ (Text "Response records must contain ONLY:")
83+ ( Above
84+ (Text " • body :: YourBodyType (required)")
85+ ( Above
86+ (Text " • headers :: Record (...) (optional)")
87+ ( Above
88+ (Text "")
89+ ( Above
90+ (Text "Valid examples:")
91+ ( Above
92+ (Text " { body: user }")
93+ ( Above
94+ (Text " { body: user, headers: { \"Location\": \"/users/123\" } }")
95+ ( Above
96+ (Text "")
97+ (Text "Do not include 'status', 'statusCode', or other fields.")
98+ )
99+ )
100+ )
101+ )
102+ )
103+ )
104+ )
105+ )
106+ )
107+ )
108+ ) =>
109+ ToResponseRL rl headers body
110+
73--------------------------------------------------------------------------------
111--------------------------------------------------------------------------------
74-- Response Construction Helpers
112-- Response Construction Helpers
75--------------------------------------------------------------------------------
113--------------------------------------------------------------------------------
src/Yoga/HTTP/API/Route/StatusCode.purs+2
@@ -9,6 +9,7 @@ import Prelude
9
9
10import Type.Proxy (Proxy(..))
10import Type.Proxy (Proxy(..))
11import Data.Newtype (class Newtype)
11import Data.Newtype (class Newtype)
12+import Prim.TypeError (class Fail, Text, Beside, Above, Quote)
12
13
13newtype StatusCode = StatusCode Int
14newtype StatusCode = StatusCode Int
14
15
@@ -225,6 +226,7 @@ instance StatusCodeMap "notExtended" where
225instance StatusCodeMap "networkAuthenticationRequired" where
226instance StatusCodeMap "networkAuthenticationRequired" where
226 statusCodeFor _ = StatusCode 511
227 statusCodeFor _ = StatusCode 511
227
228
229+
228--------------------------------------------------------------------------------
230--------------------------------------------------------------------------------
229-- Helper Functions
231-- Helper Functions
230--------------------------------------------------------------------------------
232--------------------------------------------------------------------------------