ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.27k stars 748 forks source link

StrawberryShake - Execution of fragment with subquery fails at runtime. #3274

Closed TeunKooijman closed 3 years ago

TeunKooijman commented 3 years ago

Describe the bug The following works:

query GetRacesPage($skip: Int!, $take: Int!, $searchTerm: String! = "", $order: [RaceSortInput!] = [{name: ASC}]) {
    races(
        skip: $skip, 
        take: $take, 
        order: $order,
        where: {
            or: [
                {name: {contains: $searchTerm}},
                {rarity: {name: {contains: $searchTerm}}},
                {languages: {some: {name: {contains: $searchTerm}}}}
            ]
        }) 
    {
        totalCount,
        items {
            ... RacesPage,
            size {
                name
            }   
        }
    }
}

fragment RacesPage on Race {
    id,
    name,
    baseSpeed,
    baseHealth
}

when executed like this:

 IOperationResult<IGetRacesPageResult> result = await PathfinderOfficialApi.GetRacesPage
            .ExecuteAsync(state.Page * state.PageSize, state.PageSize, searchTerm, sortInputs);

But it crashes at runtime when the query is defined like this (note that size was moved to the fragment):

query GetRacesPage($skip: Int!, $take: Int!, $searchTerm: String! = "", $order: [RaceSortInput!] = [{name: ASC}]) {
    races(
        skip: $skip, 
        take: $take, 
        order: $order,
        where: {
            or: [
                {name: {contains: $searchTerm}},
                {rarity: {name: {contains: $searchTerm}}},
                {languages: {some: {name: {contains: $searchTerm}}}}
            ]
        }) 
    {
        totalCount,
        items {
            ... RacesPage
        }
    }
}

fragment RacesPage on Race {
    id,
    name,
    baseSpeed,
    baseHealth,
    size {
        name
    }   
}

At runtime we can see that the following query was issued:

query GetRacesPage(
  $skip: Int!
  $take: Int!
  $searchTerm: String! = ""
  $order: [RaceSortInput!] = [{ name: ASC }]
) {
  races(
    skip: $skip
    take: $take
    order: $order
    where: {
      or: [
        { name: { contains: $searchTerm } }
        { rarity: { name: { contains: $searchTerm } } }
        { languages: { some: { name: { contains: $searchTerm } } } }
      ]
    }
  ) {
    __typename
    totalCount
    items {
      __typename
      ...RacesPage
      rarity {
        __typename
        name
        ... on RaceRarity {
          id
        }
      }
      ... on Race {
        id
      }
    }
  }
}
fragment RacesPage on Race {
  id
  name
  baseSpeed
  baseHealth
  size {
    __typename
    name
    ... on RaceSize {
      id
    }
  }
}

with the following variables:

{
  "skip": 0,
  "take": 25,
  "searchTerm": "",
  "order": []
}

yielding the following response (note that the size object is empty):

{
  "data": {
    "races": {
      "__typename": "RaceCollectionSegment",
      "totalCount": 11,
      "items": [
        {
          "__typename": "Race",
          "id": "a6f1c39a-feb8-4f62-95ce-1b5ffabbbbbf",
          "name": "Kobold",
          "baseSpeed": 25,
          "baseHealth": 6,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "a8430e0c-d52e-477c-a058-bc970a2113ea",
          "name": "Ratfolk",
          "baseSpeed": 25,
          "baseHealth": 6,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "3404bf2c-eb1c-4cc6-b376-450a969af548",
          "name": "Gnome",
          "baseSpeed": 25,
          "baseHealth": 6,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "519063b5-7283-4c0b-bb3a-d5d5edeba551",
          "name": "Goblin",
          "baseSpeed": 25,
          "baseHealth": 6,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "ed816fd4-9e13-43b4-b80f-30d2b5c910ff",
          "name": "Halfling",
          "baseSpeed": 25,
          "baseHealth": 6,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "14f3ef0d-aba9-4bed-8419-e9ffb1594cf5",
          "name": "Catfolk",
          "baseSpeed": 25,
          "baseHealth": 8,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "903f97e5-6972-4ad2-9377-447b7d6758a3",
          "name": "Orc",
          "baseSpeed": 25,
          "baseHealth": 10,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "8fec37b8-ec4a-4094-90a0-4e70b12fd6ce",
          "name": "Tengu",
          "baseSpeed": 25,
          "baseHealth": 6,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "7fc53559-4776-482c-910c-be3bd84d2de4",
          "name": "Human",
          "baseSpeed": 25,
          "baseHealth": 8,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "96a536c5-7fe0-4a25-af8b-881a2892b576",
          "name": "Dwarf",
          "baseSpeed": 20,
          "baseHealth": 10,
          "size": {}
        },
        {
          "__typename": "Race",
          "id": "e6ac68fc-98bf-4012-97a1-9910f988a1a4",
          "name": "Elf",
          "baseSpeed": 30,
          "baseHealth": 6,
          "size": {}
        }
      ]
    }
  }
}

And the following runtime exception:

System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.Text.Json.JsonElement.GetProperty(String propertyName)
   at Silvester.Pathfinder.Official.Web.Graphql.Generated.State.PathfinderOfficialApiEntityIdFactory.Parse(JsonElement obj) ...

Desktop (please complete the following information):

Additional context Am I doing something wrong (e.g. misunderstanding or misusing fragments) or is this a bug?

PascalSenn commented 3 years ago

Thanks for reporting :)

PascalSenn commented 3 years ago

@TeunKooijman Can you provide a schema with the query? It's hard to tell where things go wrong without a schema :)

TeunKooijman commented 3 years ago

Whoops, you're right, sorry about that. Try: http://pf2e.io/api/graphql?sdl

PascalSenn commented 3 years ago

Is this

        {
          "__typename": "Race",
          "id": "a6f1c39a-feb8-4f62-95ce-1b5ffabbbbbf",
          "name": "Kobold",
          "baseSpeed": 25,
          "baseHealth": 6,
          "size": {}
        },

part of the response you get for this?

fragment RacesPage on Race {
  id
  name
  baseSpeed
  baseHealth
  size {
    __typename
    name
    ... on RaceSize {
      id
    }
  }
}

If so this more looks like fragment issue on the server. What do you think @michaelstaib

PascalSenn commented 3 years ago

Looks like this one: https://github.com/ChilliCream/hotchocolate/issues/3166

michaelstaib commented 3 years ago

Is this fixed?

PascalSenn commented 3 years ago

@TeunKooijman This should be fixed with RC.0

TeunKooijman commented 3 years ago

Yep, this seems to be fixed. Apologies for the late reply.