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

Custom document action for publish, fails to publish #8630

Open
georgibakken opened this issue Feb 13, 2025 · 7 comments
Open

Custom document action for publish, fails to publish #8630

georgibakken opened this issue Feb 13, 2025 · 7 comments

Comments

@georgibakken
Copy link

georgibakken commented Feb 13, 2025

Describe the bug

When using custom document actions to extend the publish action, sometimes the document is not published.

It doesn't happen in a specific pattern, but more at random. Looking in the network tab, the POST publish call is not sent when this happens. When it manages to publish, the POST is sent. There is no error in the console.

To Reproduce

Steps to reproduce the behavior:

  1. Implement extension of document action
export function publishAction(originalAction, context) {
  const BetterAction = (props) => {
    const { patch } = useDocumentOperation(props.id, props.type);
    const originalResult = originalAction(props);
    return {
      ...originalResult,
      onHandle: async () => {
       

        if (props.draft.publishedAt === undefined) {
          patch.execute([{ set: { publishedAt: new Date().toISOString() } }]);
        }

        patch.execute([{ set: { lastPublishedAt: new Date().toISOString() } }]);

        originalResult.onHandle();
      },
    };
  };
  return BetterAction;
}
  1. Add it to sanity.config.ts
...
      prev.map((originalAction) => {
        if (originalAction.action === "publish") {
          return publishAction(originalAction, context);
        }
...
  1. Try publishing a document in Sanity Studio, sometimes it doesn't get published (after 5-6 times perhaps, and sometimes straight away)

Screenshots

publish-sanity-bug.mov

Which versions of Sanity are you using?

❯ sanity versions
@sanity/cli (global)          3.46.0 (latest: 3.75.0)
@sanity/dashboard              4.1.2 (up to date)
@sanity/eslint-config-studio   5.0.1 (up to date)
@sanity/icons                  3.5.7 (up to date)
@sanity/types                 3.75.0 (up to date)
@sanity/ui                    2.12.3 (latest: 2.12.4)
@sanity/vision                3.75.0 (up to date)
sanity                        3.75.0 (up to date)

What operating system are you using?
MacOS. Also experiencing this on our deployed studio

Which versions of Node.js / npm are you running?

❯ npm -v && node -v
10.7.0
v22.2.0

Additional context

I have tried the different examples in custom document actions with no luck.

@jorngeorg
Copy link
Contributor

jorngeorg commented Feb 14, 2025

I came to report the exact same issue. I have a more or less identical custom action as the above.

Some consistent patterns I have noticed:

In my document I have an array of images that seem to be central:

  1. If I don't add anything to the image array the document will be almost always publish immediately.
  2. If I add more than two images to the array there's a ~100% chance of the document NOT getting published. It will be stuck in the publishing state forever.
  3. When the document is stuck in the publishingstate, I can click Add item to the image array and the document will suddenly publish.

In the network tab, I can see that in step 2 above, there is no POST to the data/actions/
endpoint, which is is the case in step 1.

Skjermopptak.2025-02-14.kl.14.45.52.mov

@jorngeorg
Copy link
Contributor

jorngeorg commented Feb 18, 2025

I managed to track it down this line in the onHandle function blocking publishing. So when I add content do the image array validationStatus.revision isn't equal to revision when I try to publish. If I don't edit the image array validationStatus.revision is equal to revision.

validationStatus.revision !== revision

@jorngeorg
Copy link
Contributor

jorngeorg commented Feb 18, 2025

@georgibakken I wonder if your case might be slightly different to mine. Could it be that yours is a race condition of sorts?

I think you need to await your patch.execute calls, so that these are executed before you do originalResult.onHandle(). Could you try that and report back?

EDIT: ok, seems like patch.execute isn't a promise so, awaiting doesn't make sense. Sorry.

@jorngeorg
Copy link
Contributor

jorngeorg commented Feb 18, 2025

Here's my custom publish action for reference

export function createSetPublishedAtPublishAction(originalAction: any, context: any) {
  const client = context.getClient({ apiVersion: '2025-01-29' })

  const setPublishedAtPublishAction = (props: any) => {
    const originalResult = originalAction(props)

    return {
      ...originalResult,
      onHandle: async () => {
        const { draft } = props

        if (draft.publishedAt === undefined) {
          await client
            .patch(draft._id)
            .setIfMissing({ publishedAt: new Date().toISOString() })
            .commit()
        }

        originalResult.onHandle()
      },
    }
  }
  return setPublishedAtPublishAction
}

@jorngeorg
Copy link
Contributor

Interestingly, replacing client.patch with patch.execute seems to fix the issue for me. So this seems to work:

import { useDocumentOperation } from "sanity";

export function createSetPublishedAtPublishAction(originalAction: any, context: any) {
  const setPublishedAtPublishAction = (props: any) => {
    const { patch } = useDocumentOperation(props.id, props.type);

    const originalResult = originalAction(props)

    return {
      ...originalResult,
      onHandle: async () => {
        const { draft } = props

        if (draft.publishedAt === undefined) {
          patch.execute([{ set: { publishedAt: new Date().toISOString() } }]);
        }

        originalResult.onHandle()
      },
    }
  }
  return setPublishedAtPublishAction
}```


🤷 

@cwojcik-ifthen
Copy link

cwojcik-ifthen commented Feb 24, 2025

Running into the exact same problem.

Does seem strange to me that I cannot await some patch before publishing? (Or otherwise hook into when it is complete?)

@georgibakken
Copy link
Author

Thanks @jorngeorg for your input!

Originally I had some await client.patch and some patch.execute in the function, but tried to isolate it to just the patch.execute to debug it easier. I also think it is some sort of race condition, however I tried adding a delay (which looked promising in the beginning) but after adjusting the time down and then up again, it still had issues.

I agree @cwojcik-ifthen - There is however this note in the documentation

Note: Due to current technical limitations, the only way to check whether the publish action has completed is to check for the draft being null after the publish action was invoked (i.e., the code in useEffect()). We are working on improving this in the future.

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

3 participants