arangodb / arangojs

The official ArangoDB JavaScript driver.
https://arangodb.github.io/arangojs
Apache License 2.0
600 stars 106 forks source link

triggerUncaughtException on document not found #773

Closed amitabak-MA closed 1 year ago

amitabak-MA commented 2 years ago

Using arangojs@^7.8.0 Node: v16.14.2

Use case:

await graph.vertexCollection(this.graphNodesCollectionName()).update({_key: node.key}, node, { waitForSync: true, returnNew: true })

results in

node:internal/process/promises:279 triggerUncaughtException(err, true / fromPromise /); ^ ArangoError: document not found at new ArangoError (/XYZ/node_modules/arangojs/error.js:115:21) at Object.resolve (/XYZ/node_modules/arangojs/connection.js:452:37) at callback (/XYZ/node_modules/arangojs/connection.js:217:26) at IncomingMessage. (/XYZ/node_modules/arangojs/lib/request.node.js:108:21) at IncomingMessage.emit (node:events:538:35) at endReadableNT (node:internal/streams/readable:1345:12) at processTicksAndRejections (node:internal/process/task_queues:83:21) {

pluma4345 commented 2 years ago

Can you provide a more complete test case that displays this behavior? Uncaught exceptions like this are usually caused by a promise rejection not being handled, for example by invoking an async function in a setTimeout or without using await.

The exception itself is entirely expected when invoking graphVertexCollection.update with a document that does not exist in that collection, so the stack trace sadly does not provide any useful information. You can also try configuring arangojs with precaptureStackTraces: true to provide longer stack traces that may be helpful.

amitabak-MA commented 2 years ago

Hi Alan the update clause is wrapped in a try catch framework

try { await graph.vertexCollection(this.graphNodesCollectionName()).update({_key: node.key}, node, { waitForSync: true, returnNew: true }) }catch(err) { console.log({code: 'upsertGraphNode err1', msg:JSON.stringify(err)}) }

I also tried a different version adding a catch on the promise just to see if that would help ...:

try { await graph.vertexCollection(this.graphNodesCollectionName()).update({_key: node.key}, node, { waitForSync: true, returnNew: true }).catch((error) => { console.log({code: 'upsertGraphNode err1', msg:JSON.stringify(error)}) }) }catch(err) { console.log({code: 'upsertGraphNode err1', msg:JSON.stringify(err)}) }

This version also failed on the

node:internal/process/promises:279 triggerUncaughtException(err, true / fromPromise /); ^ ArangoError: document not found at new ArangoError (/XYZ/node_modules/arangojs/error.js:115:21) at Object.resolve (/XYZ/node_modules/arangojs/connection.js:452:37) at callback (/XYZ/node_modules/arangojs/connection.js:217:26)

Lastely. I run the first version with the flag (aka const conn = new Database({url,precaptureStackTraces:true})) Uncaught exception means that somewhere in the client driver a promise is being run and an exception is not caught and "rejected" in orderly fashion Even if update fails on 404 the driver is supposed to nicely "reject" the promise as to allow the application to handle it / catch it nicely

Here is the stack trace ...

node:internal/process/promises:279 triggerUncaughtException(err, true / fromPromise /); ^ ArangoError: document not found at new ArangoError (/XYZ/node_modules/arangojs/error.js:115:21) at Object.resolve (/XYZ/node_modules/arangojs/connection.js:452:37) at callback (/XYZ/node_modules/arangojs/connection.js:217:26) at IncomingMessage. (/XYZ/node_modules/arangojs/lib/request.node.js:108:21) at IncomingMessage.emit (node:events:538:35) at endReadableNT (node:internal/streams/readable:1345:12) at processTicksAndRejections (node:internal/process/task_queues:83:21) at Connection.request (/XYZ/node_modules/arangojs/connection.js:379:16) at Database.request (/XYZ/node_modules/arangojs/database.js:163:33) at GraphEdgeCollection.edge (/XYZ/node_modules/arangojs/graph.js:302:33) at ConfigurationGraph. (/XYZ/bin/dal/arangodb/arangodb.js:475:68) at step (/XYZ/bin/dal/arangodb/arangodb.js:33:23) at Object.next (/XYZ/bin/dal/arangodb/arangodb.js:14:53) at /XYZ/bin/dal/arangodb/arangodb.js:8:71 at new Promise () { response: <ref *3> IncomingMessage { _readableState: ReadableState { objectMode: false, highWaterMark: 16384, buffer: BufferList { head: null, tail: null, length: 0 }, length: 0, pipes: [], flowing: true, ended: true, endEmitted: true, reading: false, constructed: true, sync: true, needReadable: false, emittedReadable: false, readableListening: false, resumeScheduled: false, errorEmitted: false, emitClose: true, autoDestroy: true, destroyed: true, errored: null, closed: true, closeEmitted: true, defaultEncoding: 'utf8', awaitDrainWriters: null, multiAwaitDrain: false, readingMore: true, dataEmitted: true, decoder: null, encoding: null,

},
_events: [Object: null prototype] {
  end: [ [Function: responseOnEnd], [Function (anonymous)] ],
  data: [Function (anonymous)]
},
_eventsCount: 2,
_maxListeners: undefined,
socket: null,
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
rawHeaders: [
  'X-Arango-Queue-Time-Seconds',
  '0.000000',
  'X-Content-Type-Options',
  'nosniff',
  'Server',
  'ArangoDB',
  'Connection',
  'Keep-Alive',
  'Content-Type',
  'application/json; charset=utf-8',
  'Content-Length',
  '77'
],
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 404,
statusMessage: 'Not Found',
client: <ref *1> Socket {
  connecting: false,
  _hadError: false,
  _parent: null,
  _host: null,
  _readableState: ReadableState {
    objectMode: false,
    highWaterMark: 16384,
    buffer: BufferList { head: null, tail: null, length: 0 },
    length: 0,
    pipes: [],
    flowing: true,
    ended: false,
    endEmitted: false,
    reading: true,
    constructed: true,
    sync: false,
    needReadable: true,
    emittedReadable: false,
    readableListening: false,
    resumeScheduled: false,
    errorEmitted: false,
    emitClose: false,
    autoDestroy: true,
    destroyed: false,
    errored: null,
    closed: false,
    closeEmitted: false,
    defaultEncoding: 'utf8',
    awaitDrainWriters: null,
    multiAwaitDrain: false,
    readingMore: false,
    dataEmitted: true,
    decoder: null,
    encoding: null,
    [Symbol(kPaused)]: false
  },
  _events: [Object: null prototype] {
    end: [Function: onReadableStreamEnd],
    free: [Function: onFree],
    close: [Function: onClose],
    timeout: [Function: onTimeout],
    agentRemove: [Function: onRemove],
    error: [Function: bound onceWrapper] {
      listener: [Function: freeSocketErrorListener]
    }
  },
  _eventsCount: 6,
  _maxListeners: undefined,
  _writableState: WritableState {
    objectMode: false,
    highWaterMark: 16384,
    finalCalled: false,
    needDrain: false,
    ending: false,
    ended: false,
    finished: false,
    destroyed: false,
    decodeStrings: false,
    defaultEncoding: 'utf8',
    length: 0,
    writing: false,
    corked: 0,
    sync: false,
    bufferProcessing: false,
    onwrite: [Function: bound onwrite],
    writecb: null,
    writelen: 0,
    afterWriteTickInfo: null,
    buffered: [],
    bufferedIndex: 0,
    allBuffers: true,
    allNoop: true,
    pendingcb: 0,
    constructed: true,
    prefinished: false,
    errorEmitted: false,
    emitClose: false,
    autoDestroy: true,
    errored: null,
    closed: false,
    closeEmitted: false,
    [Symbol(kOnFinished)]: []
  },
  allowHalfOpen: false,
  _sockname: null,
  _pendingData: null,
  _pendingEncoding: '',
  server: null,
  _server: null,
  parser: null,
  _httpMessage: null,
  timeout: 0,
  [Symbol(async_id_symbol)]: -1,
  [Symbol(kHandle)]: <ref *2> TCP {
    reading: true,
    onconnection: null,
    [Symbol(owner_symbol)]: [Circular *1],
    [Symbol(resource_symbol)]: ReusedHandle { type: 34, handle: [Circular *2] }
  },
  [Symbol(kSetNoDelay)]: false,
  [Symbol(lastWriteQueueSize)]: 0,
  [Symbol(timeout)]: null,
  [Symbol(kBuffer)]: null,
  [Symbol(kBufferCb)]: null,
  [Symbol(kBufferGen)]: null,
  [Symbol(kCapture)]: false,
  [Symbol(kBytesRead)]: 0,
  [Symbol(kBytesWritten)]: 0,
  [Symbol(RequestTimeout)]: undefined
},
_consuming: false,
_dumped: false,
req: ClientRequest {
  _events: [Object: null prototype] {
    timeout: [Function (anonymous)],
    error: [Function (anonymous)],
    prefinish: [Function: requestOnPrefinish]
  },
  _eventsCount: 3,
  _maxListeners: undefined,
  outputData: [],
  outputSize: 0,
  writable: true,
  destroyed: true,
  _last: true,
  chunkedEncoding: false,
  shouldKeepAlive: true,
  maxRequestsOnConnectionReached: false,
  _defaultKeepAlive: true,
  useChunkedEncodingByDefault: false,
  sendDate: false,
  _removedConnection: false,
  _removedContLen: false,
  _removedTE: false,
  _contentLength: 0,
  _hasBody: true,
  _trailer: '',
  finished: true,
  _headerSent: true,
  _closed: true,
  socket: <ref *1> Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      constructed: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: true,
      destroyed: false,
      errored: null,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      dataEmitted: true,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    _events: [Object: null prototype] {
      end: [Function: onReadableStreamEnd],
      free: [Function: onFree],
      close: [Function: onClose],
      timeout: [Function: onTimeout],
      agentRemove: [Function: onRemove],
      error: [Function: bound onceWrapper] {
        listener: [Function: freeSocketErrorListener]
      }
    },
    _eventsCount: 6,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      constructed: true,
      prefinished: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: true,
      errored: null,
      closed: false,
      closeEmitted: false,
      [Symbol(kOnFinished)]: []
    },
    allowHalfOpen: false,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: null,
    _server: null,
    parser: null,
    _httpMessage: null,
    timeout: 0,
    [Symbol(async_id_symbol)]: -1,
    [Symbol(kHandle)]: <ref *2> TCP {
      reading: true,
      onconnection: null,
      [Symbol(owner_symbol)]: [Circular *1],
      [Symbol(resource_symbol)]: ReusedHandle { type: 34, handle: [Circular *2] }
    },
    [Symbol(kSetNoDelay)]: false,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(RequestTimeout)]: undefined
  },
  _header: 'GET /_db/configurations/_api/gharial/CONFIGURATIONS/edge/CONFIGURATIONS_EDGES/PG:QAT_dUIB:acRef:Mi? HTTP/1.1\r\n' +
    'authorization: Basic cm9vdDpvcGVuU2VzYW1l\r\n' +
    'content-type: text/plain\r\n' +
    'x-arango-version: 30400\r\n' +
    'Host: 127.0.0.1:8529\r\n' +
    'Connection: keep-alive\r\n' +
    '\r\n',
  _keepAliveTimeout: 0,
  _onPendingData: [Function: nop],
  agent: Agent {
    _events: [Object: null prototype] {
      free: [Function (anonymous)],
      newListener: [Function: maybeEnableKeylog]
    },
    _eventsCount: 2,
    _maxListeners: undefined,
    defaultPort: 80,
    protocol: 'http:',
    options: [Object: null prototype] {
      maxSockets: 3,
      keepAlive: true,
      keepAliveMsecs: 1000,
      scheduling: 'lifo',
      path: null
    },
    requests: [Object: null prototype] {},
    sockets: [Object: null prototype] { '127.0.0.1:8529:': [ [Socket] ] },
    freeSockets: [Object: null prototype] {
      '127.0.0.1:8529:': [ [Socket], [Socket] ]
    },
    keepAliveMsecs: 1000,
    keepAlive: true,
    maxSockets: 3,
    maxFreeSockets: 256,
    scheduling: 'lifo',
    maxTotalSockets: Infinity,
    totalSocketCount: 3,
    [Symbol(kCapture)]: false
  },
  socketPath: undefined,
  method: 'GET',
  maxHeaderSize: undefined,
  insecureHTTPParser: undefined,
  path: '/_db/configurations/_api/gharial/CONFIGURATIONS/edge/CONFIGURATIONS_EDGES/PG:QAT_dUIB:acRef:Mi?',
  _ended: true,
  res: [Circular *3],
  aborted: false,
  timeoutCb: null,
  upgradeOrConnect: false,
  parser: null,
  maxHeadersCount: null,
  reusedSocket: true,
  host: '127.0.0.1',
  protocol: 'http:',
  [Symbol(kCapture)]: false,
  [Symbol(kNeedDrain)]: false,
  [Symbol(corked)]: 0,
  [Symbol(kOutHeaders)]: [Object: null prototype] {
    authorization: [ 'authorization', 'Basic cm9vdDpvcGVuU2VzYW1l' ],
    'content-type': [ 'content-type', 'text/plain' ],
    'x-arango-version': [ 'x-arango-version', '30400' ],
    host: [ 'Host', '127.0.0.1:8529' ]
  }
},
request: ClientRequest {
  _events: [Object: null prototype] {
    timeout: [Function (anonymous)],
    error: [Function (anonymous)],
    prefinish: [Function: requestOnPrefinish]
  },
  _eventsCount: 3,
  _maxListeners: undefined,
  outputData: [],
  outputSize: 0,
  writable: true,
  destroyed: true,
  _last: true,
  chunkedEncoding: false,
  shouldKeepAlive: true,
  maxRequestsOnConnectionReached: false,
  _defaultKeepAlive: true,
  useChunkedEncodingByDefault: false,
  sendDate: false,
  _removedConnection: false,
  _removedContLen: false,
  _removedTE: false,
  _contentLength: 0,
  _hasBody: true,
  _trailer: '',
  finished: true,
  _headerSent: true,
  _closed: true,
  socket: <ref *1> Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      constructed: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: true,
      destroyed: false,
      errored: null,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      dataEmitted: true,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    _events: [Object: null prototype] {
      end: [Function: onReadableStreamEnd],
      free: [Function: onFree],
      close: [Function: onClose],
      timeout: [Function: onTimeout],
      agentRemove: [Function: onRemove],
      error: [Function: bound onceWrapper] {
        listener: [Function: freeSocketErrorListener]
      }
    },
    _eventsCount: 6,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      constructed: true,
      prefinished: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: true,
      errored: null,
      closed: false,
      closeEmitted: false,
      [Symbol(kOnFinished)]: []
    },
    allowHalfOpen: false,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: null,
    _server: null,
    parser: null,
    _httpMessage: null,
    timeout: 0,
    [Symbol(async_id_symbol)]: -1,
    [Symbol(kHandle)]: <ref *2> TCP {
      reading: true,
      onconnection: null,
      [Symbol(owner_symbol)]: [Circular *1],
      [Symbol(resource_symbol)]: ReusedHandle { type: 34, handle: [Circular *2] }
    },
    [Symbol(kSetNoDelay)]: false,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(RequestTimeout)]: undefined
  },
  _header: 'GET /_db/configurations/_api/gharial/CONFIGURATIONS/edge/CONFIGURATIONS_EDGES/PG:QAT_dUIB:acRef:Mi? HTTP/1.1\r\n' +
    'authorization: Basic cm9vdDpvcGVuU2VzYW1l\r\n' +
    'content-type: text/plain\r\n' +
    'x-arango-version: 30400\r\n' +
    'Host: 127.0.0.1:8529\r\n' +
    'Connection: keep-alive\r\n' +
    '\r\n',
  _keepAliveTimeout: 0,
  _onPendingData: [Function: nop],
  agent: Agent {
    _events: [Object: null prototype] {
      free: [Function (anonymous)],
      newListener: [Function: maybeEnableKeylog]
    },
    _eventsCount: 2,
    _maxListeners: undefined,
    defaultPort: 80,
    protocol: 'http:',
    options: [Object: null prototype] {
      maxSockets: 3,
      keepAlive: true,
      keepAliveMsecs: 1000,
      scheduling: 'lifo',
      path: null
    },
    requests: [Object: null prototype] {},
    sockets: [Object: null prototype] { '127.0.0.1:8529:': [ [Socket] ] },
    freeSockets: [Object: null prototype] {
      '127.0.0.1:8529:': [ [Socket], [Socket] ]
    },
    keepAliveMsecs: 1000,
    keepAlive: true,
    maxSockets: 3,
    maxFreeSockets: 256,
    scheduling: 'lifo',
    maxTotalSockets: Infinity,
    totalSocketCount: 3,
    [Symbol(kCapture)]: false
  },
  socketPath: undefined,
  method: 'GET',
  maxHeaderSize: undefined,
  insecureHTTPParser: undefined,
  path: '/_db/configurations/_api/gharial/CONFIGURATIONS/edge/CONFIGURATIONS_EDGES/PG:QAT_dUIB:acRef:Mi?',
  _ended: true,
  res: [Circular *3],
  aborted: false,
  timeoutCb: null,
  upgradeOrConnect: false,
  parser: null,
  maxHeadersCount: null,
  reusedSocket: true,
  host: '127.0.0.1',
  protocol: 'http:',
  [Symbol(kCapture)]: false,
  [Symbol(kNeedDrain)]: false,
  [Symbol(corked)]: 0,
  [Symbol(kOutHeaders)]: [Object: null prototype] {
    authorization: [ 'authorization', 'Basic cm9vdDpvcGVuU2VzYW1l' ],
    'content-type': [ 'content-type', 'text/plain' ],
    'x-arango-version': [ 'x-arango-version', '30400' ],
    host: [ 'Host', '127.0.0.1:8529' ]
  }
},
body: {
  code: 404,
  error: true,
  errorMessage: 'document not found',
  errorNum: 1202
},
arangojsHostId: 0,
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: {
  'x-arango-queue-time-seconds': '0.000000',
  'x-content-type-options': 'nosniff',
  server: 'ArangoDB',
  connection: 'Keep-Alive',
  'content-type': 'application/json; charset=utf-8',
  'content-length': '77'
},
[Symbol(kHeadersCount)]: 12,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0,
[Symbol(RequestTimeout)]: undefined

}, errorNum: 1202, code: 404 }

pluma commented 2 years ago

Check the stacktrace you posted again:

at GraphEdgeCollection.edge (/XYZ/node_modules/arangojs/graph.js:302:33)
at ConfigurationGraph. (/XYZ/bin/dal/arangodb/arangodb.js:475:68)

That's not the function call you posted (GraphVertrexCollection.update). But that's where the unhandled exception originates. Can you show the code in /XYZ/bin/dal/arangodb/arangodb.js lines 470-480? I'm seeing step in the stacktrace so this might be a streaming transaction.

amitabak-MA commented 1 year ago

Hi Im ooo till Wed Sept 28th Will handle this upon my return BR Ami

On Thu, Sep 22, 2022, 21:41 Alan Plum @.***> wrote:

Check the stacktrace you posted again:

at GraphEdgeCollection.edge (/XYZ/node_modules/arangojs/graph.js:302:33) at ConfigurationGraph. (/XYZ/bin/dal/arangodb/arangodb.js:475:68)

That's not the function call you posted (GraphVertrexCollection.update). But that's where the unhandled exception originates. Can you show the code in /XYZ/bin/dal/arangodb/arangodb.js lines 470-480? I'm seeing step in the stacktrace so this might be a streaming transaction.

— Reply to this email directly, view it on GitHub https://github.com/arangodb/arangojs/issues/773#issuecomment-1255410540, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMM76SDYHKFPLA4KNUSCEC3V7SR4DANCNFSM6AAAAAAQNCIYKU . You are receiving this because you authored the thread.Message ID: @.***>

amitabak-MA commented 1 year ago

Invalid bug. Miss used the API