faustjs
faustjs copied to clipboard
Bug: Infinite looping GraphQL requests with usePage and useQuery
When navigating between pages that retrieve data using usePage and useQuery the request cache appears to not totally empty between queries, resulting in the new query containing elements from the previous query - in particular it appears that data accessed/mapped through $on seem to be sticky.
If the page being navigated to doesn't contain the 'sticky' data from the previous query, the GraphQL query loops over and over again, preventing the response of all the data that does belong on the new page. If the new page does contain a matching component that consumes the same data, the cached data from the previous old query is injected.
If a page is navigated to directly, either by using instead of a Next link, or by entering the URL directly, or by reloading the page, the looping request bug is not encountered.
Applicable Versions
@faustjs/coreversion: "^0.14.1"@faustjs/reactversion: NA@faustjs/nextversion: "^0.14.0"- WordPress version: 5.8.1
Steps To Reproduce
- Visit https://elizabeth-eakins-2021-koalition.vercel.app/ and open the Network tab
- Navigate to 'Our Story' route via the header menu (page loads normally)
- Navigate to 'Rugs' route via the header menu, and observe the Network tab to see looping GraphQL requests that ask for component data that belong to the previous request (in this particular example, a component named Page_Pagebuilder_Modules_HeroLeftJustified that belongs on the 'Our Story' page, but is not on the 'Rugs' page)
- Note that the looping request also prevents the proper retrieval of the data that belongs in the current query (in this example, the Hero image on the 'Rugs' page is not properly retrieved).
Link to code example: usePage() or
useQuery().page({ id: '/', idType: PageIdType.URI, })
The current behavior
New GraphQL requests loop infinitely when it contains stale data from the previous query request
The expected behavior
New GraphQL requests do not contain stale data from the previous query, and returns data from just the current query
Hello @mediashane Happy new year. I was able to replicate the above issue using the steps to reproduce only the first time I visited the link you mentioned. Subsequently though, everything loaded fine at least for the time being even when I cleared the browser cache or when I used a different browser.
My hypothesis is that this is somehow related to Vercel but I'm not sure. I will try to visit the page again today to see if I can replicate again.
Hi @theodesp ! Thanks for jumping in. I tried again today to replicate the above issue following the steps described and was able to successfully replicate on Chrome and Firefox with Windows 10 (though my colleagues using MacOS report similar results). Something else to note is that we also encounter the same issue when working locally, for example with npm run build + npm run start, which may or may not eliminate Vercel from being the culprit. Here are some screenshots that may help diagnose the problem, and please let me know if there is any other information I can provide to help us sleuth a resolution:
Chrome

Firefox

Thank you!
Hello @mediashane I can verify the issue as follows:
- When I visit the Our story page the first time I can inspect the GraphQL request which loads correctly:
{"query":"query($id1:ID!$idType2:PageIdType$id3:ID!$idType4:RugIdType){page0:page(id:$id1 idType:$idType2){__typename id pageBuilder{__typename modules{__typename ...on Page_Pagebuilder_Modules_HeroRightJustified{textSubline textHeadline textMediaLabel textColor mediaIcon{__typename id mediaItemUrl}image{__typename id mediaItemUrl}}...on Page_Pagebuilder_Modules_TwoColumnContent{flexDirection includeParagraph alt textHeadline textParagraph backgroundColor headlineColor paragraphColor image{__typename id mediaItemUrl}}...on Page_Pagebuilder_Modules_OneColumnContent{includeParagraph textHeadline textParagraph textColor image{__typename id mediaItemUrl}}}}}rug0:rug(id:$id3 idType:$idType4){__typename rug{__typename modules{__typename collection{__typename ...on Rug_collection{id rug_collection{__typename title}}}}}id}}","variables":{"id1":"our-story","idType2":"URI","id3":"/our-story","idType4":"URI"}}
- I Navigate to 'Rugs' route via the header menu and I observe the looping request with the following GraphQL request:
{"query":"query($id1:ID!$idType2:PageIdType){page0:page(id:$id1 idType:$idType2){__typename pageBuilder{__typename modules{__typename ...on Page_Pagebuilder_Modules_HeroLeftJustified{media{__typename id mediaItemUrl}}}}id}}","variables":{"id1":"rugs","idType2":"URI"}}
and the response from the server each time is:
{"data":{"page0":{"__typename":"Page","pageBuilder":{"__typename":"Page_Pagebuilder","modules":[{"__typename":"Page_Pagebuilder_Modules_HeroCenterButton"},{"__typename":"Page_Pagebuilder_Modules_CenteredText"},{"__typename":"Page_Pagebuilder_Modules_CardList"}]},"id":"cG9zdDoxMQ=="}},"extensions":{"debug":[{"type":"DEBUG_LOGS_INACTIVE","message":"GraphQL Debug logging is not active. To see debug logs, GRAPHQL_DEBUG must be enabled."}]}}
- I reload the page and now whenever I follow the same flow( following the same steps as before I can see the page loads correctly). I can see the following GraphQL request:
{"query":"query($first1:Int$where2:RootQueryToMenuItemConnectionWhereArgs$id3:ID!$idType4:PageIdType$id5:ID!$idType6:RugIdType){menuItems0:menuItems(first:$first1 where:$where2){__typename nodes{__typename id label}}page0:page(id:$id3 idType:$idType4){__typename id pageBuilder{__typename modules{__typename ...on Page_Pagebuilder_Modules_HeroCenterButton{textOverline textHeadline buttonLabel textColor hoverTextColor media{__typename id mediaItemUrl}}...on Page_Pagebuilder_Modules_CenteredText{backgroundColor textColor textSize fontFamily cta{__typename ...on Cta{id ctaText{__typename cta}}}}...on Page_Pagebuilder_Modules_CardList{mobileSizeWide cards{__typename title description stickerText showSticker image{__typename id mediaItemUrl}link{__typename url target}}}}}}rug0:rug(id:$id5 idType:$idType6){__typename rug{__typename modules{__typename collection{__typename ...on Rug_collection{id rug_collection{__typename title}}}}}id}}","variables":{"first1":100,"where2":{"location":"PRIMARY"},"id3":"rugs","idType4":"URI","id5":"/rugs","idType6":"URI"}}
Not sure exactly why the loop is happening though AFIK the retry operations are used only in useTransactionQuery hook.
I will log a bug in our internal process tracker to investigate further. I will post any updates in this thread.
In the meantime would you be able to provide a sample React query for the two pages? For example the query of the OurStory page that triggers the Page_Pagebuilder_Modules_HeroLeftJustified and the query of the Rugs page that shows the use data accessed/mapped through $on?
Thank you in advance.
Hi @theodesp , sure thing! We're using Next.js, so we use two basic hooks for retrieving page data.
For pages generated using [...pageUri].tsx we use the following:
const { usePage } = client;
const page = usePage();
For index.tsx we use:
const pageData = useQuery().page({
id: '/',
idType: PageIdType.URI,
});
We then then access the page's attached Advanced Custom Fields modules like so: page?.pageBuilder?.modules. Within those modules we access basic component data like so: const { cards, labelColor, textColor, textLinkLabel, textLinkUrl, sectionLabel } = Page_Pagebuilder_Modules_HeroLeftJustified;
If the component data was added via WordPress admin using ACF's Flexible or Repeater content types, we access the data using $on, like so: Page_Pagebuilder_Modules_TwoColumnGallery?.rugAttributes?.$on?.Rug_attribute?.rugAttribute?.textHeadline.
In circumstances that ACF Flexible or Repeater component data is delivered in an array, we sometimes access specific entries in that array like so: Page_Pagebuilder_Modules_ThreeImageButtons.featureCards[0]?.$on?.Feature?.features?.image?.mediaItemUrl.
Under the hood, the GraphQL queries themselves are generated using npm run generate, created by GQty. Here is the query for Page_Pagebuilder_Modules_HeroLeftJustified:
Page_Pagebuilder_Modules_HeroLeftJustified: {
__typename: { __type: 'String!' },
fieldGroupName: { __type: 'String' },
media: { __type: 'MediaItem' },
textColor: { __type: 'String' },
textHeadline: { __type: 'String' },
textOverline: { __type: 'String' },
textParagraph: { __type: 'String' },
},
Navigation between pages is generally done using the basic next/link.
The plugins we use to make all this work are: FaustWP, WP GraphQL, Advanced Custom Fields PRO and WPGraphQL for Advanced Custom Fields.
Hope this helps! Let me know if there's any other data I can provide that would help us solve the issue. Thanks!
Hi @theodesp , it looks like this was fixed downstream: https://github.com/gqty-dev/gqty/issues/520
If we're using Faust, what would your recommendation be for getting this fix into our project? Will we have to wait for another release cycle for Faust? Thank you!
Hi @theodesp , it looks like this was fixed downstream: gqty-dev/gqty#520
If we're using Faust, what would your recommendation be for getting this fix into our project? Will we have to wait for another release cycle for Faust? Thank you!
that issue was not related with gqty, it was with https://github.com/supabase/pg_graphql, which doesn't seem to do anything with faustjs. no change was applied to gqty to fix that issue
I tried following the reproduction steps of this issue navigating to https://elizabeth-eakins-2021-koalition.vercel.app/ and the looping doesn't happen
Steps to reproduce it in Vercel (staging)
1- Enter in https://elizabeth-eakins-2021-koalition.vercel.app/ 2- click “our story” 3- Click “Rugs” 4- Click “From the farm” See the LOOP in dev tools
Steps to reproduce it in Vercel (staging)
1- Enter in https://elizabeth-eakins-2021-koalition.vercel.app/ 2- click “our story” 3- Click “Rugs” 4- Click “From the farm” See the LOOP in dev tools
is it possible to create a local development environment reproducing the issue? that way I can actually debug
Yeah, It couldn't be possible to make it this week. But we'll definitely do it for the next week. Many thanks. Gracias.
Hi @PabloSzx ! We've set up a Github repo and Vercel deploy that reproduces the bug. I'll also attach a video that shows steps to repro and the bug itself in action.
Github repo: https://github.com/mediashane/graphql-bug
After cloning, create a .env file in the base directory of the project and copy + save the contents of .env.local.sample into it. This will configure your local development environment to point towards the live WordPress backend. Then just npm install, npm run build and npm run start.
Here is a Vercel deploy of the repo linked above, where you can jump straight to reproducing the bug without cloning the repo: https://graphql-bug.vercel.app
Steps to reproduce it in Vercel (staging):
- Navigate to https://graphql-bug.vercel.app,
- Open Network Dev Tools tab
- Click “Our Story”
- Click “Rugs”
- Click “From the Farm”
If you don't see the looping GraphQL requests the first time, return to the home page, do a cache clearing reload and follow the sequence again. There are other occasions that this looping starts, but this is a sequence that we've found reproduces the bug consistently.
We're using the plugin WP GraphQL to expose our WordPress data, and Faust + GQty to do our queries and generate our schema locally. We think this issue is closely related to the issue you encountered and solved here: https://github.com/gqty-dev/gqty/issues/520
Here is the video: https://user-images.githubusercontent.com/14046192/150017319-3c419d6a-5484-4129-b8bf-49802477b033.mp4
Thank you in advance for all of your work, and let us know if there's anything else we can do to help!
Hello @mediashane I was also trying to clone the repo and try it locally. Unfortunately the local dev setup fails with a GraphQL Error during pre-rendering:
[GQtyError: Internal server error] {
graphQLErrors: [ { message: 'Internal server error', extensions: [Object] } ]
}
[ =] info - Generating static pages (15/22)[GQtyError: Cannot query field "paragraphText" on type "Page_Pagebuilder_Modules_CenteredText".] {
graphQLErrors: [
{
message: 'Cannot query field "paragraphText" on type "Page_Pagebuilder_Modules_CenteredText".',
extensions: [Object],
locations: [Array]
}
]
}
Is it possible to get an updated ACF export of the models as I could try to test it locally with a vanilla Wordpress install by importing the ACF models?
Hello @mediashane I was also trying to clone the repo and try it locally. Unfortunately the local dev setup fails with a GraphQL Error during pre-rendering:
[GQtyError: Internal server error] { graphQLErrors: [ { message: 'Internal server error', extensions: [Object] } ] }[ =] info - Generating static pages (15/22)[GQtyError: Cannot query field "paragraphText" on type "Page_Pagebuilder_Modules_CenteredText".] { graphQLErrors: [ { message: 'Cannot query field "paragraphText" on type "Page_Pagebuilder_Modules_CenteredText".', extensions: [Object], locations: [Array] } ] }Is it possible to get an updated ACF export of the models as I could try to test it locally with a vanilla Wordpress install by importing the ACF models?
Executing npm run generate you should have an updated Typescript schema.
Hi @theodesp I just deployed an updated schema as well, so that should fix the error you're getting, but @aitoraznar 's suggestion will also work. We're actively building out a site using this backend, so the schema is changing frequently as we progress. Thank you!
Looks like a lot of progress is being made here as well: https://github.com/gqty-dev/gqty/issues/558
@mediashane we are currently investigating the issue and documenting the steps in https://github.com/gqty-dev/gqty/issues/558
Hey @mediashane. We have a new version of Faust that does not use GQty. Maybe you can port some of your code to check it out. This should not create those issues.