#Throwing error/reject from Promise not working in Run Script

35 messages Β· Page 1 of 1 (latest)

inland hamlet
#

Hey there,

I've built a promise that filters an array of objects for a match on one of the properties, it then first resolves or rejects based on whether it finds the match and then on resolve it parses one of the properties of the object (which is an array).

The Run Script looks like this:
`module.exports = async function(data) {
const filterData = (data) => {
return new Promise((resolve, reject) => {
const filteredData = data.filter(item => item.id === "board_relation50");
if (filteredData.length === 0) {
reject(Error('No column found with the id "board_relation50". Perhaps the column ID is incorrect?'));
} else {
try {
const parsedData = JSON.parse(filteredData[0].value);
resolve(parsedData);
} catch (error) {
reject(Error('No linked Project Found. Try linking a project to the item and try again.'))
}
}
});
}

var array = {{get_monday_columns.data.data.items[0].column_values}};

return filterData(array)
    .catch(error => console.log(error))

}`

which works a treat when it resolves but when the second reject kicks in 'no linked Project found...' nothing happens. I've tried this in VS code and the reject works fine but I'm not sure how to make it work for module.exports functions.

the initial array is:
[ { "title": "Project", "text": "Album Campaign", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":78678345}]}", "id": "board_relation50" } ]

honest prism
#

Please don't hold me to this, but I don't believe that promises are currently supported in the "run script" operation (see https://docs.directus.io/configuration/flows/operations.html#run-script).
You're probably better off doing this through an extension (e.g. "hooks" or "operations"), see https://docs.directus.io/extensions/introduction.html.

inland hamlet
#

ah shoot, I mean that would make sense if that was the case cause I feel like I've tried lots of different ways to do it and each one doesn't work!

#

thank you so much for your response!

honest prism
honest prism
inland hamlet
honest prism
#

I would say so πŸ˜…

inland hamlet
#

because this won't work πŸ˜‚ :

    var array = {{get_monday_columns.data.data.items[0].column_values}}
    try {
        const filteredData = array.filter(item => item.title === "Project");
        if (filteredData.length === 0) {
            throw new Error('No project found');
        }
        const parsedData = JSON.parse(filteredData[0].value);
        return parsedData
    } catch (error) {
        console.error(error);
    }
}```
honest prism
#

Oh, right. I think async does not work in principle atm.

#

However you might be able to copy over most of your code to build an extension πŸ˜ƒ

inland hamlet
#

oh dang, yeah possibly, I was hoping to avoid doing an extension purely because I'm not the one in control of the files for my directus build (working at a company lol)

honest prism
#

Just let me know if you want to know more about it

#

(btw. somehow I suddenly have a desire for creme oeuf πŸ˜…)

inland hamlet
#

yeah I will definitely look into making a request for it! Having the ability to properly handle errors I think is something people are requesting currently anyway as there always has to be some kind of work around. I'm still learning JS so I know there's plenty things I'm probably doing wrong or missing but I have definitely seen there needs to be more error handling with the run scripts!

#

ahaha I am always in desire of a creme oeuf, especially around this season!

honest prism
# inland hamlet yeah I will definitely look into making a request for it! Having the ability to ...

I'm glad to hear that! Just to make it clear: Throwing errors in the "Run Script" operation is already supported, but async context is not. (See the "Throwing Errors" box at https://docs.directus.io/configuration/flows/operations.html#run-script)
Looking at your posted code, it seems like you're on a very good way! πŸ™Œ Good luck on your further journey!

inland hamlet
#

this is really great help, thank you @honest prism I really appreciate it! πŸ˜ƒ

honest prism
#

@inland hamlet You're welcome! In fact, this matter has continued to occupy me. So I've taken a look at the code and it seems like returning promises is possible. Sorry for the confusion! Right now, I don't have time, but I'll send you more info a little later!

inland hamlet
#

Hey that's great to hear! Don't stress too much on it as I have a few workarounds for the matter (in a way that can wholly be done in Directus Flows). The piece I seem to struggle with I think is the module.exports and how to return data or errors back to it so they correctly fail and if they do fail, that their error is logged also. Thank you so much with all your help on this!

honest prism
#

Hey @inland hamlet

As promised here's my updated answer:
As already mentioned both using async context as well as throwing errors from within the "Run Script" operation is indeed supported and possible! Sorry again for the confusion!

Just make sure that you're actually throwing the error instead of catching and logging it to the console. Moreover, make sure to use the "Filter (Blocking)" trigger type for such Flows.
Taking the original example posted by you, it should look something like this (you can omit the Promise and directly throw the error):

module.exports = async function(data) {
  const filterData = (data) => {
    const filteredData = data.filter(item => item.id === "board_relation50");
    if (filteredData.length === 0) {
      throw new Error('No column found with the id "board_relation50". Perhaps the column ID is incorrect?');
    } else {
      try {
        const parsedData =   JSON.parse(filteredData[0].value);
        return parsedData;
      } catch {
        throw new Error('No linked Project Found. Try linking a project to the item and try again.');
    }
  });

  // (not sure where 'get_monday_columns' comes from...)
  const array = {{get_monday_columns.data.data.items[0].column_values}};

  return filterData(array);
}
inland hamlet
honest prism
#

I'm very glad it's working for you! πŸ‘

Good catch on the Filter (Blocking) too as that's really important!
Jup, you'll be able to throw errors on the non blocking "Action" event too, but that doesn't prevent the event itself from being executed...
You're very welcome! πŸ˜ƒ

inland hamlet
honest prism
#

Inside the "Run Script" operation you're not able to log to the console since those scripts are executed in a VM.
If you don't have to necessarily fail the Flow, you can simply catch the error and include the message in the returned payload. In a subsequent "Log to Console" operation you can then get (e.g. via $last) and log this error message.
If you need to fail the Flow, you would have to add second "Run Script" operation after the "Log to Console" and throw the error there.

inland hamlet
#

Ahh that makes sense - I'll try that out and see how it works. I'm still grasping fully how the Run Scripts work so knowing they're in a VM makes a lot of sense. Thank you so much again for all your help!

honest prism
#

That's right, it's good to know this one; I'm probably going to add this to the docs...
You're welcome and have fun playing around with the scripts πŸ˜ƒ

honest prism
honest prism
#

Hey @inland hamlet, again I've some subsequent info for you πŸ˜… It turns out console can be used in the "Run Script" operation! So regarding your previous question, you should be able to do something like this:

module.exports = async function(data) {
  try {
    // do some things in here
  } catch (error) {
    // log error to console (customize message to your needs)
    console.log(`Run script failed: ${error.message}`)
    // rethrow error (that is, failing the operation)
    throw error;
    // or e.g. if you want to throw your own error: throw new Error(`Failed: ${error.message}`);
  }
}

Sorry again for the confusion! Since the "Run Script" operation is still pretty young, I still have to figure out things myself... However, we're constantly expanding the documentation, for example just yesterday we added some additional info about the sandbox: https://docs.directus.io/configuration/flows/operations.html#run-script

inland hamlet
#

Hey @honest prism thanks so much for the update! It's so great seeing how much progress you guys are making with this business as I'm looking to make it an integral part to our business. It's great knowing you guys are developing such a strong product!

In regards to your message, I was wondering what I might be doing wrong in this scenario below as it still doesn't show me a custom message:

    var rsReq = {{$last}};
    try{
        if(rsReq.data.data.boards[0].items.length > 0){
            throw error;
        } else {
            return rsReq;
        }
    } catch (error) {
        console.log(`Check RS failed: ${error.message}`);
    }
}```
#

or this:

    var rsReq = {{$last}};
    try{
        if(rsReq.data.data.boards[0].items.length > 0){
            throw 'There are no items';
        } else {
            return rsReq;
        }
    } catch (error) {
        console.log(`Check RS failed: ${error}`);
        throw error;
    }
}```
#

Both times they correctly throw the error but they just don't display it in the payload, I've tried loading the error in a Log to Console using {{$last}} but that doesn't want to work either

honest prism
#

Hey @inland hamlet, I'm very glad to hear that and to have you on board 🀩

Both times they correctly throw the error but they just don't display it in the payload, I've tried loading the error in a Log to Console using {{$last}} but that doesn't want to work either

Please note that you can either throw an error or return data, but not both at the same time.
What exactly would be your goal?

inland hamlet
# honest prism Hey <@268863653657182209>, I'm very glad to hear that and to have you on board οΏ½...

So basically, I would look to perform a check on something, i.e. checking if an Array contains at least one item as my Webhook catches API endpoint data and even if the endpoint delivers no result, it's still considered a success. If the array has more than one item then it returns the array (or in other words it just 'succeeds') and then if the array is empty then it stops the Flow and it would be nice to log the error that occurred. I know I could use the Log to Console operation to provide more information but sometimes a Run Script may contain more than one type of Throw for various reasons. If I can get the Run Script's Payload to contain an error message (custom or not) but also have the Run Script fail that would be my ultimate goal. Like I say, there are ways around that of course but that would be the ideal