I’ve run into something I hadn’t experienced at all while using elm so far - a completely wrong error report.
The code in question is this:
-- ...
import Json.Decode as JD
import Json.Decode.Extra as JD
import Json.Decode.Pipeline as JD
type alias ProductId =
Int
type alias LabelNumber =
String
type ProductType
= MiG
| Std100
| Std100PPE
| Std100SA
| Std100Recycling
| Ecopass
| Step
| Leather
| OrganicCotton
| OrganicCottonBlended
type alias Product =
{ productId : ProductId
, labelNumber : LabelNumber
, description : String
, state : ProductState
, productType : ProductType
}
type ProductState
= Fixed { expiresOn : Time.Posix }
| Valid { expiresOn : Time.Posix }
| Expired { expiredOn : Time.Posix }
productDecoder : JD.Decoder Product
productDecoder =
JD.succeed Product
|> JD.required "pk" JD.int
|> JD.required "label_number" JD.string
|> JD.required "description" JD.string
|> JD.custom productStateDecoder
|> JD.required "product" productTypeDecoder
printableProductDecoder : JD.Decoder Product
printableProductDecoder =
productDecoder
|> JD.andThen
(\product ->
case product.state of
Valid _ ->
JD.succeed product
Fixed _ ->
JD.succeed product
Expired _ ->
JD.fail ("Expired product " ++ product.labelNumber ++ " cannot be printed.")
)
productStateDecoder : JD.Decoder ProductState
productStateDecoder =
JD.field "product_state" JD.string
|> JD.andThen
(\productState ->
case productState of
"FIXED" ->
JD.succeed (\expiresOn -> { expiresOn = expiresOn })
|> JD.required "expires_on" JD.datetime
|> JD.map Fixed
"VALID" ->
JD.succeed (\expiresOn -> { expiresOn = expiresOn })
|> JD.required "expires_on" JD.datetime
|> JD.map Valid
"EXPIRED" ->
JD.succeed (\expiredOn -> { expiredOn = expiredOn })
|> JD.required "expires_on" JD.datetime
|> JD.map Expired
_ ->
JD.fail ("Unrecognized product state: " ++ productState)
)
productTypeDecoder : JD.Decoder ProductType
productTypeDecoder =
JD.string
|> JD.andThen
(\productType ->
case productType of
"MIG" ->
JD.succeed MiG
"OTS100" ->
JD.succeed Std100
"OTS100_PPE" ->
JD.succeed Std100PPE
"OTS100_SA" ->
JD.succeed Std100SA
"OTS100_RECYCLING" ->
JD.succeed Std100Recycling
"ECOPASSPORT" ->
JD.succeed Ecopass
"STEP" ->
JD.succeed Step
"LEATHER" ->
JD.succeed Leather
"ORGANIC_COTTON_BLENDED" ->
JD.succeed OrganicCottonBlended
"ORGANIC_COTTON" ->
JD.succeed OrganicCotton
_ ->
JD.fail (productType ++ " is not a valid product type")
)
-- ...
and the language server (tested in VSCode and Helix) complains that the printableProductDecoder
functions is wrong:
Type mismatch error.
Expected:Decoder Product
Found:Decoder { productId : ProductId, description : String, productType : ProductType, state : ProductState }
But as can be easily seen, the function just returns the result of the productDecoder
function, which is not highlighted.
Also, the elm compiler itself has no problems with this code, and it’s been running in production for a year without problems.
I am running this on NixOS, without globally installed Elm and elm-language-server, in case that makes any difference, but I would not know why.
Any help is greatly appreciated