# Need help with async server side plugin

**URL:** <https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868>\
**Category:** Plugins\
**Created:** [January 23, 2023, 12:54am UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868 "2023-01-23T00:54:44Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![kevin4](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/kevin4/32/59688_2.png) [@kevin4](https://forum.bubble.io/u/kevin4)\
**Post date:** [January 23, 2023, 12:54am UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/1 "2023-01-23T00:54:44Z")

</div>

I’m writing a server-side plugin using a node package named Axios to load a URL into an object.

I’m using the .then/.catch structure as I saw comments in this forum about implementation issues with the context.async structure.

However, it seems as if none of the code within the .then is being executed.

I base this on my sprinkling of console.log messages through the code.

The code works as a node JS file, but when I copy that code into the plugin action, it’s not working quite the same.

The plugin code is below, and further below that are the server log messages showing the console.log messages that ARE being executed.

If anyone can shed any light, I would be extremely grateful.

=== Plugin code===  
function(properties, context) {

let webpage = properties.webpage

console.log(“CustomPlugin:getLinks:Execution starting”)  
console.log("CustomPlugin:getLinks:webpage: ", webpage)

const cheerio = require(“cheerio”)  
const axios = require(“axios”)

let objectToReturn = {  
\_p\_links: [  
{  
\_p\_href: “empty”,  
\_p\_rel: “empty”,  
\_p\_text: “empty”  
}  
],  
\_p\_returnStatus: 200,  
\_p\_returnStatusText: “OK”  
}

console.log("CustomPlugin:getLinks:declared objectToReturn1: ", objectToReturn)

/\*  
const outputfile = “outputfile.htm”  
const fs = require(“fs”)  
function write2outputfile (data2write) {  
fs.writeFile(outputfile, data2write, function(err) {  
if (err) {  
console.log("fs err: ", err)  
}  
}  
)  
}  
\*/

axios.get(webpage)  
.then(response =\> {  
const $ = cheerio.load(response.data)

```
    objectToReturn._p_returnStatus = response.status
    objectToReturn._p_returnStatusText = response.statusText

    console.log("objectToReturn._p_returnStatus: ", objectToReturn._p_returnStatus)
    console.log("objectToReturn._p_returnStatusText: ", objectToReturn._p_returnStatusText)
    console.log("objectToReturn.then1: ", objectToReturn)

    /* write2outputfile(response.data) */

    const webpagelinks = $("a")
    console.log("webpagelinks: ", webpagelinks)

    webpagelinks.each(function(){
        var link = {
            "_p_href": $(this).attr('href'),
            "_p_rel": $(this).attr('rel'),
            "_p_text": $(this).text()
        }
        objectToReturn._p_links.push(link)
    })
    console.log("objectToReturn.then2: ", objectToReturn)
	return { "returnedObject" : objectToReturn }
}).catch(function (error) {
    if (error.response) {
        /* https://www.npmjs.com/package/axios#handling-errors */
        objectToReturn._p_returnStatus = error.response.status
        objectToReturn._p_returnStatusText = error.response.statusText
        console.log("objectToReturn.catch: ", objectToReturn)
        return { "returnedObject" : objectToReturn }
    }
})

```

console.log(“CustomPlugin:GetLinks:Execution stopping”)  
}

=== server log messages ===  
START RequestId: dad3583a-56c5-438e-914d-434dfaba10ee Version: $LATEST 2023-01-23T00:52:48.178Z dad3583a-56c5-438e-914d-434dfaba10ee INFO CustomPlugin:getLinks:Execution starting 2023-01-23T00:52:48.178Z dad3583a-56c5-438e-914d-434dfaba10ee INFO CustomPlugin:getLinks:webpage: [https://organicgrowth.biz/link-building/you-do-not-want-backlinks-to-your-landing-pages/](https://organicgrowth.biz/link-building/you-do-not-want-backlinks-to-your-landing-pages/) 2023-01-23T00:52:49.920Z dad3583a-56c5-438e-914d-434dfaba10ee INFO CustomPlugin:getLinks:declared objectToReturn1: { \_p\_links: [{ \_p\_href: ‘empty’, \_p\_rel: ‘empty’, \_p\_text: ‘empty’ }], \_p\_returnStatus: 200, \_p\_returnStatusText: ‘OK’ } 2023-01-23T00:52:50.197Z dad3583a-56c5-438e-914d-434dfaba10ee INFO CustomPlugin:GetLinks:Execution stopping END RequestId: dad3583a-56c5-438e-914d-434dfaba10ee REPORT RequestId: dad3583a-56c5-438e-914d-434dfaba10ee Duration: 2430.35 ms Billed Duration: 2431 ms Memory Size: 128 MB Max Memory Used: 84 MB Init Duration: 376.50 ms

---

<div class="post-metadata">

**Author:** ![dorilama](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/dorilama/32/226878_2.png) [@dorilama](https://forum.bubble.io/u/dorilama)\
**Post date:** [January 23, 2023, 7:57am UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/2 "2023-01-23T07:57:33Z")

</div>

Bubble executes your code synchronously. Anything that is asynchronous needs to be used inside a single call of `context.async` where you return the final value using the callback.  
Async code outside `context.async` is just lost.  
You also have the sync method `context.request` to make requests,.  
Also, my understanding is that there is no filesystem where your action is executed.

I hope this helps

Mariano

---

<div class="post-metadata">

**Author:** ![kevin4](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/kevin4/32/59688_2.png) [@kevin4](https://forum.bubble.io/u/kevin4)\
**Post date:** [January 23, 2023, 1:17pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/3 "2023-01-23T13:17:35Z")

</div>

Thank you.

I’ll rewrite it.

An irony is the first version of the Node JS file I wrote used an async function, which I then learned the Bubble plugin can’t accommodate.

So I rewrote it to use .then/.catch.

FWIW the fs stuff is in the original Node JS file, but is commented out in the Bubble plugin.

---

<div class="post-metadata">

**Author:** ![dorilama](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/dorilama/32/226878_2.png) [@dorilama](https://forum.bubble.io/u/dorilama)\
**Post date:** [January 23, 2023, 1:31pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/4 "2023-01-23T13:31:52Z")

</div>

The point is that Bubble runs your code in a synchronous way.  
Any code that is asynchronous must be inside `context.async` or it will not be handled by bubble’s logic.  
It doesn’t matter if you use async/await or then/catch.

Example with async/await:

```auto
const result = context.async(async (callback) => {
  try {
    const result = await doStuff();
    callback(null, result);
  } catch (error) {
    callback(error);
  }
});

```

Example with then/catch:

```auto
const result = context.async((callback) => {
  doStuff()
    .then((result) => {
      callback(null, result);
    })
    .catch((error) => {
      callback(error);
    });
});

```

---

<div class="post-metadata">

**Author:** ![kevin4](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/kevin4/32/59688_2.png) [@kevin4](https://forum.bubble.io/u/kevin4)\
**Post date:** [January 23, 2023, 2:00pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/5 "2023-01-23T14:00:55Z")

</div>

Your last comment REALLY helps.

I was misunderstanding something important here.

Thank you.

---

<div class="post-metadata">

**Author:** ![kevin4](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/kevin4/32/59688_2.png) [@kevin4](https://forum.bubble.io/u/kevin4)\
**Post date:** [January 24, 2023, 3:43pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/6 "2023-01-24T15:43:04Z")

</div>

I could use some more help. It’s possible I’m not understanding callbacks the way I thought.

I’m working off the belief that in your example, you showed a callback function being called and in order to do so that callback function was previously defined.

Below is the code that runs as a Node JS file.  
=== Start

```auto
let webpage = "https://organicgrowth.biz/link-building/you-do-not-want-backlinks-to-your-landing-pages/"

console.log("CustomPlugin:getLinks:Execution starting")
const cheerio = require("cheerio")
const axios = require("axios")

let objectToReturn = {
    _p_links: [
        {
        _p_href: "",
        _p_rel: "",
        _p_text: ""
        }
    ],
    _p_returnStatus: null,
    _p_returnStatusText: ""
}

const processResponse = function processTheResponse (error, response) {
    if (response) {
        const $ = cheerio.load(response.data)

        objectToReturn._p_returnStatus = response.status
        objectToReturn._p_returnStatusText = response.statusText

        console.log("CustomPlugin:getLinks:objectToReturn._p_returnStatus: ", objectToReturn._p_returnStatus)
        console.log("CustomPlugin:getLinks:objectToReturn._p_returnStatusText: ", objectToReturn._p_returnStatusText)
        console.log("CustomPlugin:getLinks:objectToReturn.then: ", objectToReturn)
    }
    else if (error) {
        /* HERE>>> https://www.npmjs.com/package/axios#handling-errors */
        objectToReturn._p_returnStatus = error.response.status
        objectToReturn._p_returnStatusText = error.response.statusText
        console.log("CustomPlugin:getLinks:objectToReturn.catch: ", objectToReturn)
    }
}

const getTheLinks = async (url, callback) => {
    try {
        const response = await axios.get(url)
        callback(null, response)
    }
    catch (error) {
        if (error.response) {
            callback(error)
        }
    }
}

getTheLinks(webpage, processResponse)

console.log("CustomPlugin:getLinks:Execution stopping")

```

=== End

It runs in Node and produces expected results.

When I run it as is in the bubble plugin, I expect to, and see, the same synchronous timing issue I saw before.

Then… I modify the “core” function as follows:  
=== Start

```auto
const getTheLinks = context.async(async(url, callback) => {
    try {
        const response = await axios.get(url)
        callback(null, response)
    }
    catch (error) {
        if (error.response){
            callback(error)
        }
    }
})

getTheLinks(webpage, response)

```

=== End

And after I do so, the promise times out.

The specific error messages I see are:  
Plugin action testing error:  
Plugin server action timed out

“testing” is the name of the plugin action.

I feel I’m close, but the precise syntax eludes me.

---

<div class="post-metadata">

**Author:** ![dorilama](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/dorilama/32/226878_2.png) [@dorilama](https://forum.bubble.io/u/dorilama)\
**Post date:** [January 24, 2023, 5:40pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/7 "2023-01-24T17:40:35Z")

</div>

Unformatted code is a pain to read. Have a look [here](https://meta.discourse.org/t/post-code-or-preformatted-text/188910) to see how to properly write code in a post.  
If you don’t understand how to do do it you should try first with a simpler async function. When it’s working with a simpler function then you can add your real logic.

Literally the example I posted is what you need to use, as is. Just replace `const result = await doStuff();` with the code you need to run and be sure to call the calback.

> [@kevin4](#):
>
> catch (error) {  
> if (error.response)  
> callback(error)  
> }  
> })

this is not going to work, you always need to call the callback. This is probably the reason why you get that error.

---

<div class="post-metadata">

**Author:** ![kevin4](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/kevin4/32/59688_2.png) [@kevin4](https://forum.bubble.io/u/kevin4)\
**Post date:** [January 24, 2023, 7:43pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/8 "2023-01-24T19:43:58Z")

</div>

I too have been asked to read unformatted code before and I too have responded in similar fashion.

However, I had never before heard of the three backtick trick, so I thank you for that.

I edited my above post using the three backtick trick so the code is now better formatted.

I also did follow your advise about starting simple and getting gradually more complex.

And I THOUGHT I had it, up until what I expected would be the very last step.

It’s entirely possible where I’m falling down is in my understanding of how to implement the callbacks.

Would you mind taking one last look at it? With the better formatting of the code examples above?

---

<div class="post-metadata">

**Author:** ![dorilama](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/dorilama/32/226878_2.png) [@dorilama](https://forum.bubble.io/u/dorilama)\
**Post date:** [January 24, 2023, 9:06pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/9 "2023-01-24T21:06:40Z")

</div>

The misunderstanding is that `context.async` either returns a value when you call the callback `callback(null, value)` or breaks the execution of your code throwing an error when you call the callbavk`callback(error)`.  
Also the function that you pass to `context.async` has only one parameter: the callback that you need to call to tell bubble that `context.async` has finished and can return the value.

```auto
// load here any data from lists or things

const otherResult = context.async(async (callback) => {
  try {
    const result = await axios.get('your url');
    // add here any operation, async or not
    const other = doSomething(result);
    callback(null, other);
  } catch (error) {
    // you must handle every error with a final call of the callback
    callback(error);
  }
});

const res = doYourstuff(otherResult);
// rerurns final values if you need
return {res}

```

I hope this helps.  
Send me a message and let me know how it goes.

Cheers  
Mariano

---

<div class="post-metadata">

**Author:** ![kevin4](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/kevin4/32/59688_2.png) [@kevin4](https://forum.bubble.io/u/kevin4)\
**Post date:** [January 25, 2023, 11:39pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/10 "2023-01-25T23:39:21Z")

</div>

I got it working, by once again stripping it down to it’s essence.

This time I’m literally going to add my logic back one little bit at a time, and I’ll test every tiny step right away.

Anyway,

Thank you for you help.

---

<div class="post-metadata">

**Author:** ![robert16](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/robert16/32/185675_2.png) [@robert16](https://forum.bubble.io/u/robert16)\
**Post date:** [December 8, 2023, 5:45am UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/11 "2023-12-08T05:45:06Z")

</div>

@kevin4 and @dorilama - thanks so much for this contribution! I have written up a server-side plugin and have been trying to figure out why I get errors. Am I understanding correctly that I cannot use async function(properties, context) and other async functions to follow, but instead should use context.async? Just making sure this applies to server-side functions as well… the error Bubble throws specifically instructs to use ‘async function’, so I feel like I’ve missed something…

 ![image](https://us1.discourse-cdn.com/bubble/original/3X/a/f/af5a0e8f5c2ba0ddce316c0bb4de98fb8de97174.png)

 ![image](https://us1.discourse-cdn.com/bubble/original/3X/3/4/344dd85ef94f7bc82e5a9fbed73fa417464c5e89.png)

Thanks again, cheers and happy Bubbling!

---

<div class="post-metadata">

**Author:** ![dorilama](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/dorilama/32/226878_2.png) [@dorilama](https://forum.bubble.io/u/dorilama)\
**Post date:** [December 8, 2023, 7:13am UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/12 "2023-12-08T07:13:31Z")

</div>

you are missing the new v4 api announced 8 months ago. everything in this topic is deprecated.  
If you see that error either there is a syntax error in your code or your first line is not like what buble wants (which is not valid syntax 🤷‍♂️ )

> **[Updating to Plugin API v4](https://manual.bubble.io/account-and-marketplace/building-plugins/updating-to-plugin-api-v4)**
>
> This documentation covers how to update your server-side actions to be compatible with plugin API v4, which runs on Node 18.

---

<div class="post-metadata">

**Author:** ![kevin4](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/kevin4/32/59688_2.png) [@kevin4](https://forum.bubble.io/u/kevin4)\
**Post date:** [December 8, 2023, 3:19pm UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/13 "2023-12-08T15:19:41Z")

</div>

Go with what dorilama says. He understands this much better than I do and was enormously helpful to me when I didn’t know how to use this stuff properly either.

---

<div class="post-metadata">

**Author:** ![robert16](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/robert16/32/185675_2.png) [@robert16](https://forum.bubble.io/u/robert16)\
**Post date:** [December 9, 2023, 3:42am UTC](https://forum.bubble.io/t/need-help-with-async-server-side-plugin/242868/14 "2023-12-09T03:42:24Z")

</div>

Ahh! Ok, I’ve been through a maze of docs and missed this. Thank you!!
