Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect ENUM decoding #201

Closed
horus opened this issue Aug 8, 2019 · 5 comments
Closed

Incorrect ENUM decoding #201

horus opened this issue Aug 8, 2019 · 5 comments

Comments

@horus
Copy link
Contributor

horus commented Aug 8, 2019

GHC: 8.6.4
Stack: Version 2.1.3, Git revision 0fa51b9925decd937e4a993ad90cb686f88fa282 (7739 commits) x86_64 hpack-0.31.2
Built with: lts-13.19
morpheus-graphql commit: b40fd48

Summary of my problem: a simple enum type (possibly) being decoded incorrectly by the resolver. (Maybe it's just me :-)

The following code example could be used to demonstrate it:

-- types & args
newtype TestArgs = TestArgs
    { ttt :: Level } deriving (Generic, Show)

instance GQLType TestArgs where
    type KIND TestArgs = ENUM

data Level = L0 | L1 | L2 | L3
    deriving (Show, Generic)

instance GQLType Level where
    type KIND Level = ENUM

data TestResult = TestResult
    { code :: Text
    , level :: Level
    } deriving (Generic, Show)

instance GQLType TestResult where
    type KIND TestResult = OBJECT

-- query

qTest :: TestArgs -> IORes TestResult
qTest args = resolver $ return $ Right $ TestResult
  { code  = "ok"
  , level = ttt args
  }

-- resolver

rootResolver :: GQLRootResolver IO () () Query () ()
rootResolver = GQLRootResolver
  { queryResolver        = return Query { test = qTest }
  , mutationResolver     = return ()
  , subscriptionResolver = return ()
  }

Tested with Insomnia:

example

This, however, generated the correct document for /schema.gql:

type Query { 
  test(ttt: Level!): TestResult!
}

enum Level { 
  L0
  L1
  L2
  L3
}

type TestResult { 
  code: String!
  level: Level!
}

For now, I've came up with a workaround:

-- Data/Morpheus/Resolve/Decode.hs
import           Data.Text                                  (unpack)
import           Text.Read                                  (readMaybe)
--
instance (Generic a, EnumRep (Rep a), Read a) => Decode a ENUM where
  __decode _ (Enum value) = maybe err pure $ readMaybe (unpack value)
    where err = internalArgumentError ("cannot convert to enum: " <> value)
  __decode _ isType       = internalTypeMismatch "Enum" isType

...which seemed to behave correctly. But it would require every ENUM to be an instance of Read, thus I think this is far from ideal.

Would you please help me identify the cause? And thank you for your hard work making morpheus-graphql available!

P./S.

I know there's Data.Morpheus.Resolve.Generics.EnumRep, maybe we could take advantage of the metadata of Rep?

@nalchevanidze
Copy link
Member

thank you i will fix it soon. i knew that this part of code was not written properly. i found better way to validate Union types with Generic Rep so i will update Enum decoding.
pull request will be soon.

@nalchevanidze
Copy link
Member

old implementation decoded enums could not decode properly enums more then 3 constructors, now it will

@nalchevanidze
Copy link
Member

nalchevanidze commented Aug 9, 2019

@horus thank you for finding this Bug ;)

@nalchevanidze
Copy link
Member

fixed

@horus
Copy link
Contributor Author

horus commented Aug 10, 2019

@nalchevanidze
I can confirm this merge solved my problem.
Thank you very much for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants