Skip to content

Commit 9dedc48

Browse files
committed
Improve Wire3 error message for opaque types with custom encoders/decoders
Instead of the cryptic "TOO MANY ARGS" error, provide a helpful message that explains: - The issue: opaque type with custom encoder but compiler can't generate wrapper - Three solutions: expose constructor, add compiler support, or remove from Wire3 types This helps users understand what went wrong and how to fix it when they try to use opaque types like BiSeqDict in their BackendModel/FrontendModel without compiler support.
1 parent 94a4e63 commit 9dedc48

File tree

2 files changed

+98
-11
lines changed

2 files changed

+98
-11
lines changed

extra/Lamdera/Wire3/Encoder.hs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,38 @@ encoderForType depth ifaces cname tipe =
225225
decoder =
226226
if cname == moduleName
227227
-- Referenced type is defined in the current module
228-
then (a (VarTopLevel moduleName generatedName))
228+
then
229+
-- Check if the generated name exists, if not provide helpful error
230+
case foreignTypeSig moduleName generatedName ifaces of
231+
Just _ -> (a (VarTopLevel moduleName generatedName))
232+
Nothing ->
233+
let
234+
typeNameStr = Data.Name.toChars typeName
235+
customEncoderName = Data.Name.fromChars $ "encode" ++ typeNameStr
236+
in
237+
case foreignTypeSig moduleName customEncoderName ifaces of
238+
Just _ ->
239+
error $ unlines
240+
[ ""
241+
, "-- WIRE3 ENCODER NOT SUPPORTED -----------------------------------------"
242+
, ""
243+
, "I found a custom Wire3 encoder for an opaque type:"
244+
, ""
245+
, " " ++ typeNameStr
246+
, ""
247+
, "This type cannot be used in BackendModel or FrontendModel without"
248+
, "compiler support."
249+
, ""
250+
, "To fix this:"
251+
, ""
252+
, "1. Remove this type from your BackendModel/FrontendModel, OR"
253+
, ""
254+
, "2. Expose the type constructor in the module (less efficient), OR"
255+
, ""
256+
, "3. Add compiler support (contact Lamdera team)"
257+
, ""
258+
]
259+
Nothing -> (a (VarTopLevel moduleName generatedName))
229260
else (a (VarForeign moduleName generatedName (getForeignSig tipe moduleName generatedName ifaces)))
230261

231262
in

extra/Lamdera/Wire3/Helpers.hs

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,75 @@ getForeignSig tipe moduleName generatedName ifaces =
6666
-- So add type-sig for failure encoder or decoder as appropriate.
6767
if T.isPrefixOf "w3_encode_" (T.pack $ Data.Name.toChars generatedName)
6868
then
69-
(Forall
70-
(Map.fromList [("a", ())])
71-
(TLambda (TVar "a") tLamdera_Wire_Encoder))
69+
let
70+
genNameStr = Data.Name.toChars generatedName
71+
typeNameStr = drop 10 genNameStr -- Remove "w3_encode_" prefix (10 chars)
72+
customEncoderName = Data.Name.fromChars $ "encode" ++ typeNameStr
73+
in
74+
case foreignTypeSig moduleName customEncoderName ifaces of
75+
Just _ ->
76+
error $ unlines
77+
[ ""
78+
, "-- WIRE3 ENCODER NOT SUPPORTED -----------------------------------------"
79+
, ""
80+
, "I found a custom Wire3 encoder for an opaque type:"
81+
, ""
82+
, " " ++ typeNameStr
83+
, ""
84+
, "This type cannot be used in BackendModel or FrontendModel without"
85+
, "compiler support."
86+
, ""
87+
, "To fix this:"
88+
, ""
89+
, "1. Remove this type from your BackendModel/FrontendModel, OR"
90+
, ""
91+
, "2. Expose the type constructor in the module (less efficient), OR"
92+
, ""
93+
, "3. Add compiler support (contact Lamdera team)"
94+
, ""
95+
]
96+
Nothing ->
97+
(Forall
98+
(Map.fromList [("a", ())])
99+
(TLambda (TVar "a") tLamdera_Wire_Encoder))
72100

73101
else if T.isPrefixOf "w3_decode_" (T.pack $ Data.Name.toChars generatedName)
74102
then
75-
(Forall
76-
(Map.fromList [("a", ())])
77-
(TAlias
78-
mLamdera_Wire
79-
"Decoder"
80-
[("a", TVar "a")]
81-
(Filled (TType (Module.Canonical (Name "elm" "bytes") "Bytes.Decode") "Decoder" [TVar "a"]))))
103+
let
104+
genNameStr = Data.Name.toChars generatedName
105+
typeNameStr = drop 10 genNameStr -- Remove "w3_decode_" prefix (10 chars)
106+
customDecoderName = Data.Name.fromChars $ "decode" ++ typeNameStr
107+
in
108+
case foreignTypeSig moduleName customDecoderName ifaces of
109+
Just _ ->
110+
error $ unlines
111+
[ ""
112+
, "-- WIRE3 DECODER NOT SUPPORTED -----------------------------------------"
113+
, ""
114+
, "I found a custom Wire3 decoder for an opaque type:"
115+
, ""
116+
, " " ++ typeNameStr
117+
, ""
118+
, "This type cannot be used in BackendModel or FrontendModel without"
119+
, "compiler support."
120+
, ""
121+
, "To fix this:"
122+
, ""
123+
, "1. Remove this type from your BackendModel/FrontendModel, OR"
124+
, ""
125+
, "2. Expose the type constructor in the module (less efficient), OR"
126+
, ""
127+
, "3. Add compiler support (contact Lamdera team)"
128+
, ""
129+
]
130+
Nothing ->
131+
(Forall
132+
(Map.fromList [("a", ())])
133+
(TAlias
134+
mLamdera_Wire
135+
"Decoder"
136+
[("a", TVar "a")]
137+
(Filled (TType (Module.Canonical (Name "elm" "bytes") "Bytes.Decode") "Decoder" [TVar "a"]))))
82138
else
83139
error $ "impossible getForeignSig on non-wire function: " ++ Data.Name.toChars generatedName
84140

0 commit comments

Comments
 (0)