Payload fails to run afterChange hook relialibly when deployed on Vercel (serverless)

default discord avatar
martafiixek
2 months ago
10

Hi, I have an interesting problem. I run Payload on Vercel, however, even though I change the content and save it in the admin interface, the

afterChange

hook is not ran.



I have to save the content one more time, and then it works. On

localhost

, everything is working fine.



The regeneratePage function is simple


export const regeneratePage = async ({
  doc,
  collection,
  payload,
}: {
  doc?: Document
  collection?: 'catalogues' | 'countries'
  payload: Payload
}): Promise<void> => {
  try {
    const siteUrl = process.env.SITE_URL

    let path: string | null = null

    if (collection === 'catalogues') {
      const country = await payload.findByID({
        collection: 'countries',
        id: doc.country,
      })
      path = `/${addApiSuffix(country?.label_url)}/${addApiSuffix(
        doc.publisher.name_url
      )}`
    } else if (collection === 'countries') {
      path = `/${addApiSuffix(doc?.label_url)}`
    }

    const res = await fetch(`${siteUrl}/api/revalidate`, {
      method: 'POST',
      body: path,
    })
    console.log(path)
    if (res.ok) {
      payload.logger.info(`Revalidated`)
    } else {
      payload.logger.error(`Error revalidating`)
    }
  } catch (err: unknown) {
    payload.logger.error(`Error hitting revalidate route}`)
  }
}


Looking at the Vercel function logs, I don't see any fetch request to

api/revalidate

, and I don't see Payload trying to connect to DB to find the countries



What most of the time works is saving the content two or three times in a row

  • default discord avatar
    imcorfitz
    2 months ago

    This sounds more like a timeout issue on Vercel than a problem with Payload.

    https://vercel.com/docs/concepts/limits/overview
  • default discord avatar
    martafiixek
    2 months ago

    I don't think so



    Vercel would throw a timeout error



    Also the regenerate function does not take more than 2 seconds

  • default discord avatar
    imcorfitz
    2 months ago

    Do you only have one afterChange hook - or multiple?

  • default discord avatar
    martafiixek
    2 months ago

    Two hooks, one hook one collection

  • default discord avatar
    imcorfitz
    2 months ago

    Can you share the entire collection config?

  • default discord avatar
    martafiixek
    2 months ago

    Sure, give a moment



    I'm in a public transport



    By the way thanks for the help

  • default discord avatar
    imcorfitz
    2 months ago

    I'm in a warm office with broken A/C. Slower pace is permitted.

  • default discord avatar
    martafiixek
    2 months ago

    F



    So, this is the collection:



    import { regeneratePage } from '../utilities/regeneratePage'
    import { Quote } from '../blocks/Quote'
    import { CollectionConfig } from 'payload/types'
    import { RichText } from '../blocks/RichText'
    import { Table } from '../blocks/Table'
    
    const Catalogues: CollectionConfig = {
      slug: 'catalogues',
      labels: {
        singular: 'Catalogue',
        plural: 'Catalogues',
      },
      timestamps: true,
      typescript: {
        interface: 'ICatalog',
      },
      access: {
        read: () => true,
      },
      hooks: {
        afterChange: [
          ({ doc, req: { payload } }) => {
            regeneratePage({
              collection: 'catalogues',
              doc,
              payload,
            })
          },
        ],
      },
      admin: {
        description: 'Collection of unique catalogues.',
        hideAPIURL: true,
      },
      fields: [
        {
          name: 'code',
          type: 'text',
          label: 'Code',
          admin: {
            readOnly: true,
            hidden: true,
          },
        },
        {
          name: 'title',
          type: 'json',
          label: 'Title',
          admin: {
            readOnly: true,
          },
        },
        {
          name: 'description',
          type: 'json',
          label: 'Description',
          admin: {
            readOnly: true,
            hidden: true,
          },
        },
        {
          name: 'slug',
          type: 'text',
          label: 'Slug',
          admin: {
            readOnly: true,
            hidden: true,
          },
        },
        {
          name: 'homepage',
          type: 'text',
          label: 'Homepage',
          admin: {
            readOnly: true,
            hidden: true,
          },
        },
        {
          name: 'country',
          type: 'relationship',
          relationTo: 'countries',
          hasMany: false,
          admin: {
            readOnly: true,
            hidden: true,
          },
        },
        {
          name: 'publisher',
          label: 'Publisher',
          type: 'json',
          admin: {
            readOnly: true,
            hidden: true,
          },
        },
        {
          label: 'Components',
          labels: {
            singular: 'Component',
            plural: 'Components',
          },
          name: 'layout',
          type: 'blocks',
          blocks: [Quote, Table, RichText],
        },
      ],
    }
    
    export default Catalogues


    So, it somehow fails on:



    const country = await payload.findByID({
            collection: 'countries',
            id: doc.country,
          })


    The serverless function runs for 353 ms and ends on the

    findById


    When I click on save again, the function somehow runs again (seems like)





    And then the

    /api/revalidate

    is called



    Nevermind, I fixed it



    I am dumb

    image.png
  • default discord avatar
    imcorfitz
    2 months ago

    Lol. Been there mate. Great you got it resolved. 🍾

  • default discord avatar
    martafiixek
    2 months ago

    The regenerate page did not have await and the function containing it didnt have async

    :facepalm:
Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.