Why is $.flow.exit("Exit workflow") not working properly in my custom NodeJS step?

This topic was automatically generated from Slack. You can find the original thread here.

Hi ! $.flow.exit(“Exit workflow”) is not working properly in one of my custom NodeJS step. The console log before and after the $.flow.exit(“Exit workflow”) are displayed in the logs tab.

Here is my code

import { axios } from@U05GY70D5BK/platform”
export default defineComponent({
props: {
shopify_developer_app: {
type: “app”,
app: “shopify_developer_app”,
}
},

async run({ steps, $ }) {

  console.log(“Email: ” + steps.trigger.event.body.data.object.customer_email)
  **if** (steps.trigger.event.body.data.object.customer_email == ‘[test@test.com](mailto:test@test.com)’) {
    console.log(“workflow exit”)
    $.flow.exit(“Exit workflow”)
    console.log(“workflow exit2”)
  }

It seems like you’re encountering an issue where $.flow.exit("Exit workflow") is not stopping the execution of your workflow as expected. The console.log statements before and after the $.flow.exit call are both appearing in the logs, which should not happen if $.flow.exit is functioning correctly. Based on the code you’ve provided, the $.flow.exit call should indeed stop the workflow from executing any further code. However, if you’re seeing logs after the $.flow.exit call, it suggests that the workflow is not exiting early as intended. Here’s a revised version of your code with the correct usage of $.flow.exit: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { shopify_developer_app: { type: "app", app: "shopify_developer_app", }, }, async run({ steps, $ }) { console.log("Email: " + steps.trigger.event.body.data.object.customer_email); if (steps.trigger.event.body.data.object.customer_email === '[test@test.com](mailto:test@test.com)') { console.log("workflow exit"); return $.flow.exit("Exit workflow"); } // Any code here will only run if the email is not '[test@test.com](mailto:test@test.com)' console.log("workflow exit2"); }, }); Please note the following changes: 1. I’ve used return before $.flow.exit to ensure that the function exits immediately. 2. I’ve replaced the email comparison to use a strict equality check (===) and removed the mailto link formatting to match the email string correctly. If you’re still experiencing issues after making these changes, please visit Pipedream Support for further assistance.

Hi , there is no need to replace the email comparison to use a strict equality check (===) as the 2 console.log shows that the if logic is working properly.

Also, you’re proposal to use a return before $.flow.exit will continue the workflow to the next step, which is not what I am looking for. I am looking to exit the workflow

Based on your description, it seems you’re looking to exit the workflow early without proceeding to the next step. In Pipedream, you can achieve this by using $.flow.exit(). This function will immediately end the execution of the workflow, and no remaining code in that step or any steps below will run. Here’s an example of how you can use $.flow.exit(): export default defineComponent({ async run({ steps, $ }) { // Your logic here if (/** your condition **/) { // This will end the workflow early return $.flow.exit(); } // Any code here will not run if the condition above is true }, }); Remember, any code after the $.flow.exit() call will not be executed, so you don’t need to use a return statement before it. The workflow will end as soon as $.flow.exit() is called. If you have any further questions or need additional support, please visit https://pipedream.com/support.

return $.flow.exit() is the correct syntax. We catch that on our end and end the workflow. The return is necessary. See Writing Node.js in Steps and let me know if that helps.

Hi Dylan ! Thanks for your answer, it works well now with the return. But any clue why on others workflows the return is not necessary ?

Can you share the relevant code snippet for that other workflow? We always require the return, so I’m not sure off hand

if (steps.trigger.event.body.app_id == "58931412993" ) {
      /**********************************************************************************************
       ** CUSTOM APP ORDER
       **********************************************************************************************/

      //Order created by internal app, do nothing
      console.log("Order from custom internal app");
      $.flow.exit("Exit workflow as source : " + steps.trigger.event.body.source_name);
    } else if (steps.trigger.event.body.source_name == "shopify_draft_order") {
      /**********************************************************************************************
       ** DRAFT ORDER
       **********************************************************************************************/
      console.log("shopify_draft_order");

      // call invoice workflow
      (...)

      // Log the response from the API call
      console.log(response);
      $.flow.exit("Exit workflow as source : " + steps.trigger.event.body.source_name);

do you successfully see the end state for the event in your workflow inspector? i.e. are you seeing the UI we show that we ended the workflow in that case?

with the message that you pass in $.flow.exit?

overall I’d recommend using return everywhere, since that’s how $.flow.exit is intended to be called. If that’s not working, happy to look into that issue more!

image.png

Yes I can see it

I agree I should use the return everytime, but I was wondering if there was a bug here

in that code above, I’m seeing the string passed to $.flow.exit as:

"Exit workflow as source : " + ...

but in the screenshot I see “Exit workflow as …“, with no “source”. Can you check if you’re using $.flow.exit anywhere else in that step?

it is called 3 times:
$.flow.exit(“Exit workflow as source : ” + steps.trigger.event.body.source_name);
$.flow.exit(“Exit workflow as source : ” + steps.trigger.event.body.source_name);
$.flow.exit(“Exit workflow as ” + steps.trigger.event.body.source_name);

got it, I think this may be because it’s called at the very end of the step, so based on the implementation, it’s expected that would work. In general we need it to be called last to signal to our execution environment that the workflow will end, so return is typically necessary.

in Node.js, since the last expression called is returned, no return is necessary if it’s the last thing run in the step

you can add return there and it will also work