Rdflib.js fetch failing


#1

I went through the lunch break tutorial last week. As it sometimes happens with tutorials, I was able to go through it without understanding too much :sweat_smile:. So I decided to try again, this time from scratch.

In the end I’ve had to copy-paste some of the tutorial code. I’m getting a better grip of the basics, but I’ve hit a snag with the rdflib.js fetch. I get the following message:

I uploaded the code to GitHub in case anyone wants to check it out:

I’m not sure if it’s a mistake I’m making, a problem with the library or a problem with the build system I’ve set up. Any tips welcome!


#2

I still haven’t figured this out, but I’ve done some investigation. It turns out that this error message is being generated in fetcher.js#L815:

// ...
return this._fetch(actualProxyURI, options).then(
  response => this.handleResponse(response, docuri, options),
  error => {
    let dummyResponse = {
      url: actualProxyURI,
      status: 999, // @@ what number/string should fetch failures report?
      statusText:
        (error.name || 'network failure') +
        ': ' +
        (error.errno || error.code || error.type),
      responseText: error.message,
      headers: {}, // Headers() ???
      ok: false,
      body: null,
      bodyUsed: false,
      size: 0,
      timeout: 0
    };
    console.log(
      'Fetcher: <' + actualProxyURI + '> Non-HTTP fetch error: ' + error
    );
    return this.failFetch(
      options,
      'fetch failed: ' + error,
      999,
      dummyResponse
    ); // Fake status code: fetch exception

    // handleError expects a response so we fake some important bits.
    /* this.handleError(, docuri, options) */
  }
);
// ...

So, this._fetch is failing and the second callback (error => {...) is being called. The first line of the error message is generated by the console.log, then this.failFetch is called, which adds the second console.log and finally rejects the promise with the error that appears last on my console:

failFetch (options, errorMessage, statusCode, response) {
    this.addStatus(options.req, errorMessage)

    if (!options.noMeta) {
      this.store.add(options.original, ns.link('error'), errorMessage)
    }

    let meth = (options.method || 'GET').toUpperCase()
    let isGet = meth === 'GET' || meth === 'HEAD'

    if (isGet) {  // only cache the status code on GET or HEAD
      if (!options.resource.sameTerm(options.original)) {
        console.log('@@ Recording failure  ' + meth + '  original ' + options.original +
          '( as ' + options.resource + ') : ' + statusCode)
      } else {
        console.log('@@ Recording ' + meth + ' failure for ' + options.original + ': ' + statusCode)
      }
      this.requested[Uri.docpart(options.original.uri)] = statusCode
      this.fireCallbacks('fail', [options.original.uri, errorMessage])
    }

    var err = new Error('Fetcher: ' + errorMessage)

    // err.ok = false // Is taken as a response, will work too @@ phase out?
    err.status = statusCode
    err.statusText = errorMessage
    err.response = response

    return Promise.reject(err)
}

I’m still none the wiser, but I’ll report if I make any findings.


#3

Is the URI perhaps malformed? For example, does it contain spaces? Rdflib expects well-formed URIs which means URI-encoding them before rdflib sees them.


#4

Thanks, Jeff. I actually solved the problem a couple of hours ago with the help of @naqerf. I’m planning to post an explanation tomorrow.

It was a bit of a dumb mistake and it’s solved by setting to "#" the action attribute of the form element wrapping the view button that is triggering the fetch.

Alternatively, these two other changes also work:

  • adding a pound symbol to the URL so that it becomes localhost:8000/#
  • calling preventDefault() on the event like so:
$('#view').click(async function loadProfile(e) {
  e.preventDefault();
  // ...

I don’t fully understand how forms work (I always get away with copy pasting some code) but my understanding is that the form submit action and the fetch were interfering in some way :man_shrugging:?

I’ll take the chance to do some reading on basics of HTML forms to see if I get a better understanding of what was happening. Any pointers appreciated.

Thanks Jeff for taking the time to look into this :raised_hands: