Difficulty setting return in a workflow

I have a js code block in a workflow and am having difficulty correctly setting the return value.

Any ideas?

async function prepSlack() {
  let slackUserId = null;
  let slackConversationId = null;

  // Set slackUserId based on getOperator.slack_id or call getSlackUserId
  console.log("getOperator data:", getOperator.data);
  if (getOperator.data && getOperator.data.length > 0 && getOperator.data[0].slack_id) {
    slackUserId = getOperator.data[0].slack_id;
    console.log("Using existing slackUserId:", slackUserId);
  } else {
    try {
      console.log("Fetching Slack user ID for email:", prepVisit.data.operatorEmail);
      const email = prepVisit.data.operatorEmail;
      const slackUserIdResult = await getSlackUserId(email);
      slackUserId = slackUserIdResult?.id || null;
      console.log("Fetched slackUserId:", slackUserId);
    } catch (error) {
      console.error("Error fetching Slack user ID:", error);
      throw new Error("Failed to fetch Slack user ID.");
    }
  }

  // Set slackConversationId based on getOperator.slack_channel or call getSlackConversationId
  if (slackUserId) {
    if (getOperator.data[0].slack_channel) {
      slackConversationId = getOperator.data[0].slack_channel;
      console.log("Using existing slackChannel from getOperator as slackConversationId:", slackConversationId);
    } else {
      try {
        console.log("Fetching Slack conversation ID for slackUserId:", slackUserId);
        const slackConversationIdResult = await getSlackConversationId(slackUserId);
        slackConversationId = slackConversationIdResult?.id || null;
        console.log("Fetched slackConversationId:", slackConversationId);
      } catch (error) {
        console.error("Error fetching Slack conversation ID:", error);
        throw new Error("Failed to fetch Slack conversation ID.");
      }
    }
  } else {
    console.log("slackUserId is null, skipping Slack conversation ID fetch.");
  }

  // Update the operators table with the Slack user and conversation IDs
  if (slackUserId && slackConversationId && (!getOperator.data[0].slack_id || !getOperator.data[0].slack_channel || getOperator.data[0].slack_id !== slackUserId || getOperator.data[0].slack_channel !== slackConversationId)) {
    try {
      console.log("Updating operator Slack IDs with slackUserId and slackConversationId:", slackUserId, slackConversationId);
      await updateOperatorSlackIds(slackUserId, slackConversationId);
      console.log("Successfully updated operator Slack IDs.");
    } catch (error) {
      console.error("Error updating operator Slack IDs:", error);
      throw new Error("Failed to update operator Slack IDs.");
    }
  } else {
    console.log("Skipping operator Slack IDs update. slackUserId or slackConversationId is null.");
  }

  if (slackConversationId) {
    console.log("Returning slackConversationId:", slackConversationId);
    return slackConversationId;
  } else {
    console.error("Failed to determine Slack conversation ID.");
    throw new Error("Failed to determine Slack conversation ID.");
  }
  
}

prepSlack();
1 Like

Hey @Shawn_Optipath,

Might need a little bit of time for me to break this whole block down to help diagnose why you aren't getting responses.

I did throw this code block into chatGPT and here is what it gave me :sweat_smile: some decent ideas for trouble shooting.

The function structure you’ve created seems well-organized. However, a few possible issues might prevent it from returning data correctly. Here are some suggestions to troubleshoot and fix it:

  1. Verify Async Data Fetching Functions: Ensure that getSlackUserId and getSlackConversationId are correctly implemented as async functions and that they resolve the expected data structure (e.g., slackUserIdResult?.id and slackConversationIdResult?.id).

  2. Check getOperator and prepVisit Data Structure: Verify that getOperator.data and prepVisit.data.operatorEmail are populated as expected. You could add more console.log() statements to see what is being returned.

  3. Function Execution Context: Since you are calling prepSlack() directly, if you’re running this in an environment where top-level await is not allowed, you need to ensure prepSlack() is called in an async context. For example:

(async () => {
    try {
        await prepSlack();
    } catch (error) {
        console.error("prepSlack failed:", error);
    }
})();
  1. Conditional Logic for Updates: In the update section, if slackUserId and slackConversationId are both non-null, but equal to current values in getOperator.data[0], it should skip updating. This logic seems correct, but double-check updateOperatorSlackIds to ensure it doesn’t throw an error unnecessarily.

  2. Return Value Check: At the end of the function, if slackConversationId is null, you’ll throw an error. Make sure this behavior is intentional. To catch where the issue occurs, add console.log() statements just before the return.

Here's the adjusted block with additional logging for troubleshooting:

async function prepSlack() {
  let slackUserId = null;
  let slackConversationId = null;

  // Logging to trace data structure issues
  console.log("Operator data:", getOperator.data);
  console.log("PrepVisit data:", prepVisit.data);

  if (getOperator.data && getOperator.data.length > 0 && getOperator.data[0].slack_id) {
    slackUserId = getOperator.data[0].slack_id;
    console.log("Using existing slackUserId:", slackUserId);
  } else {
    try {
      const email = prepVisit.data.operatorEmail;
      console.log("Fetching Slack user ID for email:", email);
      const slackUserIdResult = await getSlackUserId(email);
      slackUserId = slackUserIdResult?.id || null;
      console.log("Fetched slackUserId:", slackUserId);
    } catch (error) {
      console.error("Error fetching Slack user ID:", error);
      throw new Error("Failed to fetch Slack user ID.");
    }
  }

  if (slackUserId) {
    if (getOperator.data[0].slack_channel) {
      slackConversationId = getOperator.data[0].slack_channel;
      console.log("Using existing slackChannel:", slackConversationId);
    } else {
      try {
        console.log("Fetching Slack conversation ID for slackUserId:", slackUserId);
        const slackConversationIdResult = await getSlackConversationId(slackUserId);
        slackConversationId = slackConversationIdResult?.id || null;
        console.log("Fetched slackConversationId:", slackConversationId);
      } catch (error) {
        console.error("Error fetching Slack conversation ID:", error);
        throw new Error("Failed to fetch Slack conversation ID.");
      }
    }
  } else {
    console.log("No slackUserId; skipping conversation fetch.");
  }

  if (slackUserId && slackConversationId && 
      (!getOperator.data[0].slack_id || 
       !getOperator.data[0].slack_channel || 
       getOperator.data[0].slack_id !== slackUserId || 
       getOperator.data[0].slack_channel !== slackConversationId)) {
    try {
      console.log("Updating operator Slack IDs:", slackUserId, slackConversationId);
      await updateOperatorSlackIds(slackUserId, slackConversationId);
      console.log("Successfully updated operator Slack IDs.");
    } catch (error) {
      console.error("Error updating operator Slack IDs:", error);
      throw new Error("Failed to update operator Slack IDs.");
    }
  } else {
    console.log("No update needed for operator Slack IDs.");
  }

  if (slackConversationId) {
    console.log("Returning slackConversationId:", slackConversationId);
    return slackConversationId;
  } else {
    console.error("Could not determine Slack conversation ID.");
    throw new Error("Failed to determine Slack conversation ID.");
  }
}

// Wrapping the function call in an async IIFE to handle errors
(async () => {
  try {
    const conversationId = await prepSlack();
    console.log("Conversation ID:", conversationId);
  } catch (error) {
    console.error("prepSlack failed:", error);
  }
})();

If the above changes don't fix the issue, consider breaking down the function further to isolate the problem. Let me know if there’s any specific area where it’s still not functioning as expected.

1 Like

sorry, I should have shown the logs. I plugge in your code and here is an extract of the logs.


[log] Using existing slackUserId: 123
Tue 2024-10-29 12:13:18
[log] Using existing slackChannel: 456
Tue 2024-10-29 12:13:18
[log] No update needed for operator Slack IDs.
Tue 2024-10-29 12:13:18
[log] Returning slackConversationId: 456
Tue 2024-10-29 12:13:18
[log] Conversation ID: 456

I am only looking to return the slackConversationId so I can reference it in the next block like:
{{ prepSlack.data.slackConversationId }}

Notice the error The value has to be of type 'string | number', you provided a value of type 'object'

1 Like

I think top level await is fine in here. I tried it and it works. I think the original warning is correct. You were never returning anything. You wrote prepSlack, and you called it. But you never returned antyhing at the top level. You don't need to define prepSlack. You can just write:

let slackUserId = null;
let slackConversationId = null;

// Set slackUserId based on getOperator.slack_id or call getSlackUserId
console.log("getOperator data:", getOperator.data);
if (getOperator.data && getOperator.data.length > 0 && getOperator.data[0].slack_id) {
  slackUserId = getOperator.data[0].slack_id;
  console.log("Using existing slackUserId:", slackUserId);
} else {
  try {
    console.log("Fetching Slack user ID for email:", prepVisit.data.operatorEmail);
    const email = prepVisit.data.operatorEmail;
    const slackUserIdResult = await getSlackUserId(email);
    slackUserId = slackUserIdResult?.id || null;
    console.log("Fetched slackUserId:", slackUserId);
  } catch (error) {
    console.error("Error fetching Slack user ID:", error);
    throw new Error("Failed to fetch Slack user ID.");
  }
}

// Set slackConversationId based on getOperator.slack_channel or call getSlackConversationId
if (slackUserId) {
  if (getOperator.data[0].slack_channel) {
    slackConversationId = getOperator.data[0].slack_channel;
    console.log("Using existing slackChannel from getOperator as slackConversationId:", slackConversationId);
  } else {
    try {
      console.log("Fetching Slack conversation ID for slackUserId:", slackUserId);
      const slackConversationIdResult = await getSlackConversationId(slackUserId);
      slackConversationId = slackConversationIdResult?.id || null;
      console.log("Fetched slackConversationId:", slackConversationId);
    } catch (error) {
      console.error("Error fetching Slack conversation ID:", error);
      throw new Error("Failed to fetch Slack conversation ID.");
    }
  }
} else {
  console.log("slackUserId is null, skipping Slack conversation ID fetch.");
}

// Update the operators table with the Slack user and conversation IDs
if (slackUserId && slackConversationId && (!getOperator.data[0].slack_id || !getOperator.data[0].slack_channel || getOperator.data[0].slack_id !== slackUserId || getOperator.data[0].slack_channel !== slackConversationId)) {
  try {
    console.log("Updating operator Slack IDs with slackUserId and slackConversationId:", slackUserId, slackConversationId);
    await updateOperatorSlackIds(slackUserId, slackConversationId);
    console.log("Successfully updated operator Slack IDs.");
  } catch (error) {
    console.error("Error updating operator Slack IDs:", error);
    throw new Error("Failed to update operator Slack IDs.");
  }
} else {
  console.log("Skipping operator Slack IDs update. slackUserId or slackConversationId is null.");
}

if (slackConversationId) {
  console.log("Returning slackConversationId:", slackConversationId);
  return slackConversationId;
} else {
  console.error("Failed to determine Slack conversation ID.");
  throw new Error("Failed to determine Slack conversation ID.");
}
2 Likes

Fantastic. That worked. Probably staring at it for too long. Thank you.

1 Like