arangojs icon indicating copy to clipboard operation
arangojs copied to clipboard

Collection#documentExists return JSON Parse error: Unexpected EOF

Open shaynlink opened this issue 10 months ago • 1 comments

When I use database.collection('medias').documentExists('medias/123'), actually return a JSON Parse error: Unexpected EOF error.

Bun: 1.2.2 arangoJS: 9.2.0 and 10.1.1 Arango: 3.7.10 Community Edition (I can't change it)

Code:

const database = await ArangoService.instance();
const collection = database.collection('medias');
await collection.documentExists('medias/123');

output:

Response (0 KB) {
  ok: true,
  url: "http://xxx:8529/_db/xxx/_api/document/medias/123",
  status: 200,
  statusText: "OK",
  headers: Headers {
    "x-content-type-options": "nosniff",
    "connection": "Keep-Alive",
    "content-type": "application/json; charset=utf-8",
    "content-length": "451",
    "server": "ArangoDB",
  },
  redirected: false,
  bodyUsed: false,
  Blob (0 KB)
}

690 |             headers.set("x-arango-trx-id", this._transactionId);
691 |         }
692 |         if (allowDirtyRead) {
693 |             headers.set("x-arango-allow-dirty-read", "true");
694 |         }
695 |         return new Promise((resolve, reject) => {
      ^
SyntaxError: JSON Parse error: Unexpected EOF
      at <parse> ()
      at parse (unknown:1:1)
      at processTicksAndRejections (native:7:39)
      at /xxx/node_modules/arangojs/esm/connection.js:695:20
      at request (/xxx/node_modules/arangojs/esm/connection.js:661:19)
      at request (/xxx/node_modules/arangojs/esm/databases.js:233:16)
      at /xxx/node_modules/arangojs/esm/collections.js:308:40
      at documentExists (/xxx/node_modules/arangojs/esm/collections.js:300:31)
      at /xxx/repository/MediaRepository.ts:14:42
      at processTicksAndRejections (native:7:39)

shaynlink avatar Feb 04 '25 14:02 shaynlink

Interesting! This is probably a bug related to the body handling because the response to the HEAD request still sends the content-type and content-length headers but an empty body. We're checking for res.body before processing it:

if (res.body) {
  if (task.options.expectBinary) {
    res.parsedBody = await res.blob();
  } else if (contentType?.match(MIME_JSON)) {
    res.parsedBody = await res.json();
  } else {
    res.parsedBody = await res.text();
  }
}

Source: https://github.com/arangodb/arangojs/blob/main/src/connection.ts#L846-L854

But presumably Node.js shares the behavior MDN mentions for browsers so this check doesn't actually work:

Note: Current browsers don't actually conform to the spec requirement to set the body property to null for responses with no body (for example, responses to HEAD requests, or 204 No Content responses).

Source: https://developer.mozilla.org/en-US/docs/Web/API/Response/body

Browsers not supporting this should be enough of a reason not to rely on this check.

I'm no longer going to be with ArangoDB next month so @cmyk47 or @shd8 might want to take a look at this.

pluma avatar Mar 25 '25 09:03 pluma