Why Am I Facing Errors in Automation That Has Been Running for Months?

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

I am getting this erro and I am not sure why, this automation has been running for months and just today had this issues, the weird thing is that when I run the java script code on visual studio code it runs without problem

image.png

const fetch = require('node-fetch');

const collectionId = "id"
const keyApi = "key"
const essUrl = "cnnot share"

// Parameters to get the item listed from the webflow CMS
const url = cannot share;
const options = {
method: 'GET',
headers: {
accept: 'application/json',
authorization: Bearer ${keyApi}``
}
};

// Function to fetch data fom the ESS API
const essData = async (key) => {
const data = await fetch(essUrl + key)
const jsonData = await data.json()
//console.log(jsonData)
return jsonData
};

// Function to list all the items of the webflow CMS
const webflowItems = async (e) => {
let urlOffset = url + ?offset=${e}``
const itemList = await fetch(urlOffset, options);
const itemJson = await itemList.json();
return itemJson.items
}

// Function to update the items on webflow CMS
const update = async (key) => {
//Call to the ESS API, brings the data from the company
const ess = await essData(key);
//Call to the webflow API list the items on the CMS
const webFlow = await webflowItems(200);

`await webFlow.map(async (element, index) => {`
    `//Find the item on ess that matches and itme on webflow`
    `let updatedObject = ess.find(e => e.id === parseInt(element["ess-id"]));`
    `// If a match is found upddate the value on webflow with the data on ess`
    `if (updatedObject !== undefined) {`
        `//create a URL tor tigger that specific item on webflow`
        `let itemID = element._id`
        `let urlupdate = url + `/${itemID}` + "?live=true";`

        `// create the values that will be updated on webflow CMS`
        `let slug = element.slug;`
        `let name = element.name;`
        `let price = updatedObject.price;`
        `price = price.split('.')[0]`
        `price = parseInt(price)`
        `let availUnits = updatedObject.available_unit_count;`

        `// Method for the call and authentication on webflow API`
        `const options2 = {`
            `method: 'PUT',`
            `headers: {`
                `accept: 'application/json',`
                `'content-type': 'application/json',`
                `authorization: `Bearer ${keyApi}``
            `},`
            `body: JSON.stringify({`
                `fields: {`
                    `slug: slug,`
                    `name: name,`
                    `_archived: false,`
                    `_draft: false,`
                    `price: price,`
                    `"available-units": availUnits,`
                `}`
            `})`
        `};`

        `// Delay each iteration by 1 second using setTimeout and await`
        `await new Promise(resolve => setTimeout(resolve, 700 * index));`

        `// Fetch call to make update` 
        `fetch(urlupdate, options2)`
            `.then(res => res.json())`
            `.then(json => console.log(json))`
            `.catch(err => console.error('error:' + err));`
    `}`
`})`

}

const keys = [
// a list of keys
]

keys.forEach((key) => update(key))

as i mention the code runs just perfect when I run it locally

can you show me how to properly wrap this code so it works in a Pipedream Node.js code step?

Certainly! To ensure your code runs properly within a Pipedream Node.js code step, you’ll need to wrap any asynchronous operations in an async function and use await to ensure they complete before the step finishes. Here’s a general structure for how you might wrap your code: ```
export default defineComponent({ async run({ steps, $ }) { // your asynchronous code here // make sure to use await with any function that returns a Promise }, })

Thaks I am trying to wrap this piece of code **const** essData = **async** (key) => {
**const** data = **await** fetch(essUrl + key)
**const** jsonData = **await** data.json()
//console.log(jsonData)
**return** jsonData
};

const essData = async (key) => {
    const data = await fetch(essUrl + key)
    const jsonData = await data.json()
    //console.log(jsonData)
    return jsonData
};

this is the code I am tying wrap ```
const essData = async (key) => {
const data = await fetch(essUrl + key)
const jsonData = await data.json()
//console.log(jsonData)
return jsonData
};

Based on the code snippet you’ve provided, it looks like you’re trying to fetch JSON data from a URL constructed with a base essUrl and a key. To wrap this code in a Pipedream component, you would use the axios library provided by the Pipedream platform to make the HTTP request. Here’s how you could convert your function into a Pipedream component: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { essUrl: { type: "string", label: "ESS URL", description: "The base URL for the ESS data", }, key: { type: "string", label: "Key", description: "The key to append to the ESS URL", }, }, async run({ steps, $ }) { const url = `${this.essUrl}${this.key}`; const response = await axios($, { url, }); return response; }, }); In this component: - We define two props, essUrl and key, which allow the user to input the base URL and key when they use the component. - We use the axios function provided by @pipedream/platform to make the HTTP request. - The run method returns the JSON response directly, which will be the output of this step in the workflow. Remember to replace essUrl and key with the actual values when you use this component in a workflow. If you have any further questions or need additional assistance, feel free to ask!

I am getting this error

Error
TypeError: Cannot read properties of undefined (reading 'props') 
Error: TypeError: Cannot read properties of undefined (reading 'props')
    at handleError (/var/task/common.js:38:40)
    at Runner.runUserCode (file:///var/task/lambda_handler.mjs:903:9)
    at async Runner.run (file:///var/task/lambda_handler.mjs:732:5)
    at async Runtime.handler (file:///var/task/lambda_handler.mjs:954:22)
(node)

Apparently I have to wrap any asynchronous operations in an async function and use await to ensure they complete before the step finishes using this format

async run({ steps, $ }) {
    return await getMetaData(this.url)
  },

but I am not sure how to do it for my code tht looks like this

const essData = async (key) => {
    const data = await fetch(essUrl + key)
    const jsonData = await data.json()
    //console.log(jsonData)
    return jsonData
};

// Function to list all the items of the webflow CMS
const webflowItems = async (e) => {
    let urlOffset = url + `?offset=${e}`
    const itemList = await fetch(urlOffset, options);
    const itemJson = await itemList.json();
    return itemJson.items
}



// Function to update the items on webflow CMS
const update = async (key) => {
    //Call to the ESS API, brings the data from the company
    const ess = await essData(key);
    //Call to the webflow API list the items on the CMS
    const webFlow = await webflowItems(0);


    await webFlow.map(async (element, index) => {
        //Find the item on ess that matches and itme on webflow
        let updatedObject = ess.find(e => e.id === parseInt(element["ess-id"]));
        // If a match is found upddate the value on webflow with the data on ess
        if (updatedObject !== undefined) {
            //create a URL tor tigger that specific item on webflow
            let itemID = element._id
            let urlupdate = url + `/${itemID}` + "?live=true";

            // create the values that will be updated on webflow CMS
            let slug = element.slug;
            let name = element.name;
            let price = updatedObject.price;
            price = price.split('.')[0]
            price = parseInt(price)
            let availUnits = updatedObject.available_unit_count;

            // Method for the call and authentication on webflow API
            const options2 = {
                method: 'PUT',
                headers: {
                    accept: 'application/json',
                    'content-type': 'application/json',
                    authorization: `Bearer ${keyApi}`
                },
                body: JSON.stringify({
                    fields: {
                        slug: slug,
                        name: name,
                        _archived: false,
                        _draft: false,
                        price: price,
                        "available-units": availUnits,
                    }
                })
            };

            // Delay each iteration by 1 second using setTimeout and await
            await new Promise(resolve => setTimeout(resolve, 700 * index));

            // Fetch call to make update 
            fetch(urlupdate, options2)
                .then(res => res.json())
                .then(json => console.log(json))
                .catch(err => console.error('error:' + err));
        }
    })
}

It looks like you’re trying to use asynchronous functions within a Pipedream workflow, but you’re encountering an error related to the props being undefined. This error typically occurs when you’re trying to access this.props outside of a Pipedream component’s run method, or if the props are not properly defined within the component. To resolve this issue, you need to encapsulate your asynchronous operations within the run method of a Pipedream component. Here’s how you can structure your code as a Pipedream component: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { // Define your props here if needed, for example: apiKey: { type: "string", label: "API Key", description: "Your Webflow API key", }, essUrl: { type: "string", label: "ESS URL", description: "The URL to your ESS API", }, webflowUrl: { type: "string", label: "Webflow URL", description: "The URL to your Webflow CMS", }, }, async run({ steps, $ }) { const essData = async (key) => { const response = await axios($, { url: `${this.essUrl}${key}`, headers: { // Add any required headers here }, }); return response.data; }; const webflowItems = async (e) => { let urlOffset = `${this.webflowUrl}?offset=${e}`; const response = await axios($, { url: urlOffset, headers: { // Add any required headers here Authorization: `Bearer ${this.apiKey}`, }, }); return response.data.items; }; // Define your update function here, using axios to make HTTP requests // and this.props to access any properties you've defined // Your logic to update the items on webflow CMS }, }); Please note that you need to replace the fetch calls with axios provided by the @pipedream/platform package, as shown in the example. Also, make sure to define any required props and use this.props to access their values within the run method. If you need further assistance, please provide more

do you mena that fetch dos not work in piedream I must use axios?

In Pipedream, when making HTTP requests in Node.js code steps, you should use the axios constructor provided by the @pipedream/platform package instead of the standard fetch API. This version of axios is customized for the Pipedream environment and includes enhancements that make it easier to use within Pipedream workflows. Here’s how you can use axios in a Pipedream Node.js code step: import { axios } from "@pipedream/platform"; export default defineComponent({ async run({ steps, $ }) { return await axios($, { url: "https://api.example.com/data", // You can add method, headers, body, etc. here as needed }); }, }); Remember to replace https://api.example.com/data with the actual URL you want to make the request to. If you need to set headers, method, or body, you can add those to the configuration object passed to axios.

hey can you give a detailed explanation of how to change the fetch action in mi code for axios actions, how to properly set my props, and how to use the wrap for my asynchronous operations

async run({ steps, $ }) {
    return await getMetaData(this.url)
  },

this is how my code looks

import fetch from 'node-fetch';


const collectionId = "an id"
const keyApi = "a key"
const essUrl = "a url"

// Parameters to get the item listed from the webflow CMS
const url = `a url`;
const options = {
    method: 'GET',
    headers: {
        accept: 'application/json',
        authorization: `Bearer ${keyApi}`
    }
};


// Function to fetch data fom the ESS API

const essData = async (key) => {
    const data = await fetch(essUrl + key)
    const jsonData = await data.json()
    //console.log(jsonData)
    return jsonData
};

// Function to list all the items of the webflow CMS
const webflowItems = async (e) => {
    let urlOffset = url + `?offset=${e}`
    const itemList = await fetch(urlOffset, options);
    const itemJson = await itemList.json();
    return itemJson.items
}



// Function to update the items on webflow CMS
const update = async (key) => {
    //Call to the ESS API, brings the data from the company
    const ess = await essData(key);
    //Call to the webflow API list the items on the CMS
    const webFlow = await webflowItems(0);


    await webFlow.map(async (element, index) => {
        //Find the item on ess that matches and itme on webflow
        let updatedObject = ess.find(e => e.id === parseInt(element["ess-id"]));
        // If a match is found upddate the value on webflow with the data on ess
        if (updatedObject !== undefined) {
            //create a URL tor tigger that specific item on webflow
            let itemID = element._id
            let urlupdate = url + `/${itemID}` + "?live=true";

            // create the values that will be updated on webflow CMS
            let slug = element.slug;
            let name = element.name;
            let price = updatedObject.price;
            price = price.split('.')[0]
            price = parseInt(price)
            let availUnits = updatedObject.available_unit_count;

            // Method for the call and authentication on webflow API
            const options2 = {
                method: 'PUT',
                headers: {
                    accept: 'application/json',
                    'content-type': 'application/json',
                    authorization: `Bearer ${keyApi}`
                },
                body: JSON.stringify({
                    fields: {
                        slug: slug,
                        name: name,
                        _archived: false,
                        _draft: false,
                        price: price,
                        "available-units": availUnits,
                    }
                })
            };

            // Delay each iteration by 1 second using setTimeout and await
            await new Promise(resolve => setTimeout(resolve, 700 * index));

            // Fetch call to make update 
            fetch(urlupdate, options2)
                .then(res => res.json())
                .then(json => console.log(json))
                .catch(err => console.error('error:' + err));
        }
    })
}


const keys = [
    "a list of keys"
]


keys.forEach((key) => update(key))

To convert your fetch actions to axios and properly set up your props for asynchronous operations in Pipedream, you’ll need to follow these steps: 1. Replace the fetch import with the axios import from the @pipedream/platform package. 2. Define your props to include any dynamic values you want to pass to your component, such as API keys or URLs. 3. Use axios to make HTTP requests, passing the $ context and the request configuration object. 4. Use async/await syntax to handle asynchronous operations. Here’s how you can refactor your code to use axios within a Pipedream component: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { collectionId: { type: "string", label: "Collection ID", }, keyApi: { type: "string", label: "API Key", }, essUrl: { type: "string", label: "ESS URL", }, url: { type: "string", label: "Webflow CMS URL", }, }, async run({ steps, $ }) { const headers = { accept: 'application/json', authorization: `Bearer ${this.keyApi}`, }; const essData = async (key) => { const response = await axios($, { url: `${this.essUrl}${key}`, headers, }); return response; }; const webflowItems = async (e) => { let urlOffset = `${this.url}?offset=${e}`; const response = await axios($, { url: urlOffset, headers, }); return response.items; }; // ... rest of your update function ... const keys = [ // ... your list of keys ... ]; for (const key of keys) { await update(key); } }, }); Please note that I’ve added props for collectionId, keyApi, essUrl, and url. You’ll need to fill in the rest of your update function with the axios equivalent of your fetch calls. Also, I’ve used a for...of loop to iterate over your keys, as this will ensure that the updates are performed sequentially. Remember to handle rate limits and add appropriate error handling for

in this piece of code what wpudl represent the actual values of the prop, I see type and label, but not a value fo

Based on the information provided, it seems you are asking about the values that would be assigned to properties (props) in a Pipedream component. In the context of Pipedream components, props are used to define inputs that the user can provide when setting up a component, such as a trigger or an action. Here’s a simplified example to illustrate how props are used in a component: export default defineComponent({ props: { exampleProp: { type: "string", label: "Example Label", description: "This is an example prop", }, }, async run({ steps, $ }) { // You can access the value provided by the user for exampleProp like this: const value = this.exampleProp; console.log(value); // This will log the actual value the user entered for exampleProp }, }); In this example, exampleProp is a property of the props object. It has a type of “string” and a label which is the human-readable name displayed in the UI. The actual value for exampleProp is provided by the user when they configure the component in the Pipedream UI. Inside the run method, you can access this value with this.exampleProp. If you need further clarification or have additional questions, feel free to ask!

in this piece of code what wpudl represent the actual values of the prop, I see type and label, but not a value for collectionId, KeyApi,essUrl and url export default defineComponent({
props: {
collectionId: {
type: “string”,
label: “Collection ID”,
},
keyApi: {
type: “string”,
label: “API Key”,
},
essUrl: {
type: “string”,
label: “ESS URL”,
},
url: {
type: “string”,
label: “Webflow CMS URL”,
},
},

The type and label in the props of a Pipedream component are used to define the expected data type and the user-friendly name for the input fields that will appear in the Pipedream UI. The actual values for collectionId, keyApi, essUrl, and url are provided by the user when they configure the component in their workflow. When a user adds this component to their workflow, they will see input fields with the labels “Collection ID”, “API Key”, “ESS URL”, and “Webflow CMS URL”. The user will fill in these fields with their specific values, which will then be accessible in the component’s run method as this.collectionId, this.keyApi, this.essUrl, and this.url. Here’s an example of how these values might be used in a run method: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { collectionId: { type: "string", label: "Collection ID", }, keyApi: { type: "string", label: "API Key", }, essUrl: { type: "string", label: "ESS URL", }, url: { type: "string", label: "Webflow CMS URL", }, }, async run({ steps, $ }) { return await axios($, { method: "GET", url: this.url, // This will use the value provided by the user for "Webflow CMS URL" headers: { "Authorization": `Bearer ${this.keyApi}`, // This will use the value provided by the user for "API Key" }, params: { "collection_id": this.collectionId, // This will use the value provided by the user for "Collection ID" }, }); }, }); In this example, the axios call uses the values provided by the user for collectionId, keyApi, and url to make an API request. The essUrl prop is defined but not used in this example. If needed, it would be accessed in a similar way using this.essUrl.

how do I set this function with axios and use the run wrap

async run({ steps, $ }) {
    return await getMetaData(this.url)
  },
const essData = async (key) => {
    const data = await fetch(essUrl + key)
    const jsonData = await data.json()
    //console.log(jsonData)
    return jsonData
};