"not_ready_key" Error when calling external api from Action

Hi,

I am trying to develop a plugin with an element that collects some data from our api, the plugin knows the token and the base uri.

I have created a Load “Action” and am trying to call the api using standard fetch (although i have used axios too, with exactly the same issue). The load function is as follows:

function(instance, properties, context) {
    try{
        console.log('METADATA load')
        context.async(async callback => {
        try { 
            const props = instance.data.properties;
            const url = `${props.apiurl}app/metadata/${props.EntityId}/${props.AppliesTo.trim()}?valueNames=${encodeURI(props.Name.trim())}`;
            value = "";
               const response = await fetch(url, {
                    method: 'GET', // *GET, POST, PUT, DELETE, etc.
                    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
                    headers: {
                      'Authorization': props.token,
                      'Rezi-Api-Version' : '1.0',
                      'Accept': 'application/json, text/plain, */*',
                      'Content-Type': 'application/json;charset=UTF-8'
                    }
                  });
               const result = await response.json();
            value = result[props.Name.trim()];
            callback(null, value);
        } catch (err) {
            console.error(`Error Loading METADATA = ${err}`)
            callback(null);
        } finally {
            instance.publishState("Value", value);
            instance.triggerEvent("Loaded");
        }
    });
    }catch(loadErr){
        console.error(`Error Loading METADATA2 = ${JSON.stringify(loadErr, null, 4)}`)
    }
    }

When this code gets to the line: const response = await fetch…
an error appears in the browser that looks like this thrown by the last catch statement

Error Loading METADATA2 = {
    "not_ready_key": {
        "_listener_count": 0,
        "_turned_dependency": {
            "runs": {
                "1671013671238x614": {
                    "id": "1671013671238x614",
                    "_subs": [],
                    "_is_destroyed": false,
                    "dont_track_scheduling": false,
                    "_has_dependency": true
                }
            },
            "count": 1,
            "no_scheduled_collection": true
        },
        "timeout_length": null,
        "name": "Pluginservice.context.async async callback => {\n        try { \n            const props = instance.data.properties;\n\n\n            const url = `${props.apiurl}app/metadata/${props.EntityId}/${props.AppliesTo.trim()}?valueNames=${encodeURI(props.Name.trim())}`;\n            value = \"\";\n  \n               const response = await fetch(url, {\n                    method: 'GET', // *GET, POST, PUT, DELETE, etc.\n                    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached\n                    headers: {\n                      'Authorization': props.token,\n                      'Rezi-Api-Version' : '1.0',\n                      'Accept': 'application/json, text/plain, */*',\n                      'Content-Type': 'application/json;charset=UTF-8' \n                    }\n                  });\n               const result = await response.json();\n\n  \n            \n            value = result[props.Name.trim()];\n\n            callback(null, value);\n        } catch (err) {\n            console.error(`Error Loading METADATA = ${err}`)\n            callback(null);\n\n        } finally {\n            instance.publishState(\"Value\", value);\n            instance.triggerEvent(\"Loaded\");\n\n        }\n    }cmMfA",
        "_turned": false
    }
}

And whilst this load function works the first time even with this error (calls the api, gets the value etc), it will not work a second time once this error has occurred.

I cannot find any documentation of this error on bubble, or for axios or fetch. I suspect its something to do with the context.async call, but i appear to be following the patterns i have seen elsewhere for this, unless I’m being blind!

@jared.gibb any ideas?

Kind Regards

Ian Pearce

1 Like

This is because the internal execution mechanism of bubble actions.
https://manual.bubble.io/account-and-marketplace/building-plugins/loading-data

Your code can be executed multiple times if some of the data is “not ready”. That error is part of bubble internal mechanism but it’s not handled if it throws inside the async call.

What you can try is moving outside the context.async call any variable that you need to calculate using the properties of the action.

As the comments that you find in a new action say: first load your data (create your variables using properties), then do the opration (call context.async)

Hi Dorilama

I couldnt figure it out, i tried moving everything outside of the context.async, but nothing seemed to work. Eventually I resorted to doing a promise pattern and this works just fine, although not as elegant.

Thanks for your help, i couldnt find any sign of this error or documentation on the web at least you pointed me in the right direction!

Kind regards

Ian

There is no documentation on the web about this error because is part of the bubble logic to run custom code.

from the documentation (my previous link)

try...catch statements that contain data load functions will catch the special errors we throw, which can cause this mechanism to fail to work properly.

Understanding this part of the documentation is critical to plugin development.

Everything that uses the properties object needs to be before the business logic of your action and you can’t wrap it in a try...catch statement.

You don’t know if bubble needs to make requests to the database to get the data passed in properties.

Also be careful on when you call the callback in context.async because that will end it.

This topic is great at explaining how to use it.

1 Like