Lucky
Lucky

Reputation: 711

Using Datastore's pagination example causes " Error: 13 INTERNAL: Request message serialization failure: invalid encoding"

I'm using this page as a starting point.

My code looks like this:

app.get('/gizmos', async (req, res, next) => {

  const pageSize = 3;
  const resText = [];
  const cursor = req.query.cursor;

  try {
    let query = datastore.createQuery('gizmo').limit(pageSize);

    if (cursor) {
      query = query.start(cursor);
    }

    const [results] = await datastore.runQuery(query);
    const [gizmos] = results[0];

    const info = results[1];

    if (info.moreResults !== Datastore.NO_MORE_RESULTS) {
    // If there are more results to retrieve, the end cursor is
    // automatically set on `info`. To get this value directly, access
    // the `endCursor` property.
        const nextUrl = req.protocol + "://" + req.get("host") + req.baseUrl + "?cursor=" + info.endCursor;
        console.log(nextUrl);
    }

    gizmos.forEach(gizmo => {

      const id = gizmo[Datastore.KEY].id;

      resText.push({
         "id" : id,
         "name" : gizmo.name,
  
      });

    });

    res
      .status(200)
      .set('Content-Type', 'text/plain')
      .send(resText)
      .end();
  } catch (error) {
    next(error);
  }
});

But it fails with a 500 error. The logs say this:

Error: 13 INTERNAL: Request message serialization failure: invalid encoding at Object.callErrorFromStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client.js:176:52)
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141) at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181) at /workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78 at processTicksAndRejections (internal/process/task_queues.js:75:11)

Any ideas?

Upvotes: 3

Views: 2140

Answers (3)

Gaff
Gaff

Reputation: 5667

It looks like you are passing the cursor via query string, which should be encoded and decoded via encodeURIComponent / decodeURIComponent.

Decoding:

if (cursor) {
  query = query.start(decodeURIComponent(cursor));
}

Encoding:

encodeURIComponent(info.endCursor)

Upvotes: 0

Trong Nghia
Trong Nghia

Reputation: 53

The info.endCursor may contain reserved Characters

var set1 = ";,/?:@&=+$"; // Reserved Characters

Change the code of your http request to "?cursor=" + encodeURIComponent(info.endCursor);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

Upvotes: 1

Rafael Lemos
Rafael Lemos

Reputation: 5829

Posting this as a community wiki as it's based on @JimMorrison's comment.

The issue here is that you are passing an array in your res.send(), but it is expecting a string, given the text/plain content type, so you need to convert this array into a string before using it here. You can do that by doing using the following code:

res
  .status(200)
  .set('Content-Type', 'text/plain')
  .send(JSON.stringify(resText))
  .end();

Upvotes: 1

Related Questions