Is there a timeout on Jovo interactions?

amazon-alexa

#1

Still working on my podcast player variant.

There’s one interaction which may take a few second before my Jovo code is ready to respond. I am seeing

Local server did not return a valid JSON response:
undefined

in the console log before I have finished computing the answer and returned anything.

The only thing I can think of which might explain this would be if Jovo’s server had a time limit of only a few seconds, and was timing out before I was done.

Is there indeed a timeout? If so, can I adjust it, and if not what’s the alternative?

(Basically I need to search a few URIs to determine what the next one available will be. That isn’t blindingly fast.)

I found https://github.com/jovotech/jovo-framework/issues/118 which appears similar. But all other interactions are working fine; there’s no sign of a port conflict on them. It’s just this one, which is doing a sequence of XMLHttpRequests and checking status, incrementing until it finds a match, that is blowing up.


#2

Hey @keshlam

Does it happen using the Jovo debugger?

This is how I tried to reproduce:

function wait() {
  return new Promise((resolve, reject) =>  {
    setTimeout(resolve, 15000);
  })
}

app.setHandler({
  async LAUNCH() {
    await wait();
    return this.toIntent('HelloWorldIntent');
  },
});

It doesn’t timeout in my example. Even with an operation of 15s. Could you provide some code to reproduce?


#3

Subroutines

function uriExists(uri) {
    var xhr = new XMLHttpRequest();
    xhr.open('HEAD', uri, false);
    xhr.send();
 
    if (xhr.status == "404") { // Might want to generalize to "doesn't start w/ 2"
        return false;
    } else {
        return true;
    }
};

function todayDateOnly() {
    return dateOnly(new Date()) 
}
function dateOnly(date) {
    date.setHours(0)
    date.setMinutes(0)
    date.setSeconds(0)
    date.setMilliseconds(0)
    return date
}

called from the handler function (where index is a Date, not an integer):

getNextEpisode: function(index) {
    console.log("getNextEpisode from index: "+index)
    nowDate=todayDateOnly()
    searchDate=datefns.parseISO(index)
    searchDate=datefns.addDays(searchDate,1)
    while (searchDate <= nowDate) {
        try {
    	if (uriExists(dateToUri(searchDate)) ) {
    	    return dateToEpisode(searchDate)
    	}
    	searchDate=datefns.addDays(searchDate,1)
        } catch(err) {
            // Tossed this in thinking problem might be a transient exception; didn't help.
            console.log("uriExists test failure; retrying "+searchDate)
        }
    }
    return null;
},

In the failing case, it’s having to search by a bit over a month. I don’t have a measurement of exactly how long that takes, but it’s producing the error message just before I find the next episode.

Is there a way to turn on better debugging reports?

(This is stopgap code, admittedly. The podcast I’m accessing has a very deep archive, but doesn’t have a machine-readable index file for all of it. Filenames have a date field rather than an episode number, so the quickest way to get things going was to navigate by date.)

The code isn’t checked in yet because I’m accessing URIs that haven’t officially been published. I should factor that out so I can check in the rest…


#4

Thanks

I see that you are using XMLHttpRequest. As far as I know, it’s not natively supported by NodeJs. Do you use an extra package?

It’s probably an asynchronous/synchronous/callback issue. This example has the uriExists function with async/await

const { App, HttpService } = require('jovo-framework');

async function uriExists(uri) {
  try {
    const request = await HttpService.head(uri);
    return request.status === 200;
  } catch (e) {
    return false;
  }
}


app.setHandler({
  async LAUNCH() {
    console.log(await uriExists('https://www.jovo.tech'));
    console.log(await uriExists('https://www.jovo.tech/asdjlasdjlkasjd'));
    ...
  },
});

This returns

true
false

#5

Thanks; I’ll give that a spin. I’m still not fluent in Javascript, so I’m swiping some solutions from the net, and async isn’t well illustrated.

I notice you’re using await, and async, at both levels. Is that necessary or just good practice? (My first attempt to adopt this didn’t work as expected, so I presume I’m doing something wrong in async usage.)


#6

Yes, it’s necessary for both levels.

await only works in functions with async and async always returns a Promise that needs to be awaited.

Feel free to post your progress. Maybe I can help you there.


#7

Hm. Which would mean we’d need async/await all the way up the call tree, right?

Not sure that actually makes sense architecturally. (Not sure it doesn’t either.)


#8

yes