Thomas Mahringer created TINKERPOP-2197:
-------------------------------------------

             Summary: gremlin javascript - Error: read ECONNRESET  at 
TLSWrap.onStreamRead - websocket error
                 Key: TINKERPOP-2197
                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2197
             Project: TinkerPop
          Issue Type: Bug
          Components: driver, javascript
    Affects Versions: 3.4.0
         Environment: windows 10 ent, 10.016299
nodejs 11.10.1
gemlin javascript 3.4.0
express 4.16.4
            Reporter: Thomas Mahringer
         Attachments: gremlin-ws-error.png

*Environment*

 

I'm running a nodejs express app and connect to MSFT azure gremlin through the 
js driver:

 
{code:java}
connect() {
 this.authenticator = new     
  Gremlin.driver.auth.PlainTextSaslAuthenticator(
  `/dbs/${this.config.database}/colls/${this.config.collection}`,  
   this.config.primaryKey)
   this.client = new Gremlin.driver.Client(
     this.config.endpoint,
     { 
       authenticator: this.authenticator, 
       traversalsource: "g", 
       rejectUnauthorized: true, 
       mimeType: "application/vnd.gremlin-v2.0+json" 
    }
}
);

{code}
 

 

The app calls various gremlin commands through the string + "query parameter" 
syntax, e.g. 
{code:java}
await this.client.submit("g.V().hasLabel(label)", {label: "Person"});{code}
 

All the queries work fine but when the app is idling for about 5-10 minutes, 
the nodejs process exits with the above error. None of my error handlers are 
hit. 

So I debugged the gremlin js code and found out where the error is thrown: 

It's the error handler in gremlin/lib/driver/connection.js, which gets 
installed in "open"
{code:java}
open() {
  if (this.isOpen) {
    return Promise.resolve();
  }
  if (this._openPromise) {
    return this._openPromise;
  }

  this.emit('log', `ws open`);

  this._ws = new WebSocket(this.url, {
    headers: this.options.headers,
    ca: this.options.ca,
    cert: this.options.cert,
    pfx: this.options.pfx,
    rejectUnauthorized: this.options.rejectUnauthorized
  });


  this._ws.on('message', (data) => this._handleMessage(data));
  // ******* Install error handler
  this._ws.on('error', (err) => this._handleError(err));

...
}

_handleError(err) {
 this.emit('log', `ws error ${err}`);
 console.error("***************** Added log to improve debug ****************")
 this._cleanupWebsocket();
 this.emit('error', err); // Error ist thrown here
}{code}
 

In the debugger I can see that the error is caused in *stream_base_commons.js:*
{code:java}
function onStreamRead(arrayBuffer) {
 const nread = streamBaseState[kReadBytesOrError];
 const handle = this;
 const stream = this[owner_symbol];
 stream[kUpdateTimer]();
 if (nread > 0 && !stream.destroyed) {
   const offset = streamBaseState[kArrayBufferOffset];
   const buf = new FastBuffer(arrayBuffer, offset, nread);
   if (!stream.push(buf)) {
     handle.reading = false;
     if (!stream.destroyed) {
       const err = handle.readStop();
       if (err)
         stream.destroy(errnoException(err, 'read'));
     }
   }
   return;
 }
 if (nread === 0) {
   return;
 }
 if (nread !== UV_EOF) {
   /*Happens here >>>> */ return stream.destroy(errnoException(nread, 'read'));
 }
...
}

{code}
 

So my questions are:
 * Why is the error thrown in the first place. (After app idles for 5-10 
minutes)
 ** What happens in "this.emit('error', err);" in "Connection._handleError".
 * What is the right place to catch the error? I've of course wrapped the 
"submit" code above in try/catch (in case of async/await) or as 
"then(...).catch()..." (in case of using the promise directly). Since the error 
causes nodejs to exit, it's quite bad.:) 
 ** As it all happens asynchronously, I would need something like an "onError" 
handler. But the web socket and its handler (this._ws.on('error')...) are 
within the  "Connection" class.

The attached image shows the stack trace in Visual Studio Code Debugger.

Any help is appreciated!

Thanks

Thomas 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to