Coder Social home page Coder Social logo

neo4j / neo4j-javascript-driver Goto Github PK

View Code? Open in Web Editor NEW
832.0 78.0 145.0 31.87 MB

Neo4j Bolt driver for JavaScript

Home Page: https://neo4j.com/docs/javascript-manual/current/

License: Apache License 2.0

HTML 0.26% JavaScript 65.03% Shell 0.01% PowerShell 0.01% TypeScript 34.45% Dockerfile 0.09% Python 0.14%
driver javascript neo4j database bolt neo4j-driver

neo4j-javascript-driver's Introduction

Neo4j Driver for JavaScript

This is the official Neo4j driver for JavaScript.

Starting with 5.0, the Neo4j Drivers will be moving to a monthly release cadence. A minor version will be released on the last Friday of each month so as to maintain versioning consistency with the core product (Neo4j DBMS) which has also moved to a monthly cadence.

As a policy, patch versions will not be released except on rare occasions. Bug fixes and updates will go into the latest minor version and users should upgrade to that. Driver upgrades within a major version will never contain breaking API changes.

See also: https://neo4j.com/developer/kb/neo4j-supported-versions/

Resources to get you started:

What's New in 5.x

Including the Driver

In Node.js application

Stable channel:

npm install neo4j-driver

Pre-release channel:

npm install neo4j-driver@next

Please note that @next only points to pre-releases that are not suitable for production use. To get the latest stable release omit @next part altogether or use @latest instead.

var neo4j = require('neo4j-driver')

Driver instance should be closed when Node.js application exits:

driver.close() // returns a Promise

otherwise application shutdown might hang or it might exit with a non-zero exit code.

In web browser

We build a special browser version of the driver, which supports connecting to Neo4j over WebSockets. It can be included in an HTML page using one of the following tags:

<!-- Direct reference -->
<script src="lib/browser/neo4j-web.min.js"></script>

<!-- unpkg CDN non-minified -->
<script src="https://unpkg.com/neo4j-driver"></script>
<!-- unpkg CDN minified for production use, version X.Y.Z -->
<script src="https://unpkg.com/[email protected]/lib/browser/neo4j-web.min.js"></script>

<!-- jsDelivr CDN non-minified -->
<script src="https://cdn.jsdelivr.net/npm/neo4j-driver"></script>
<!-- jsDelivr CDN minified for production use, version X.Y.Z -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/browser/neo4j-web.min.js"></script>

This will make a global neo4j object available, where you can create a driver instance with neo4j.driver:

var driver = neo4j.driver(
  'neo4j://localhost',
  neo4j.auth.basic('neo4j', 'password')
)

From 5.4.0, this version is also exported as ECMA Script Module. It can be imported from a module using the following statements:

// Direct reference
import neo4j from 'lib/browser/neo4j-web.esm.min.js'

// unpkg CDN non-minified , version X.Y.Z where X.Y.Z >= 5.4.0
import neo4j from 'https://unpkg.com/[email protected]/lib/browser/neo4j-web.esm.js'

// unpkg CDN minified for production use, version X.Y.Z where X.Y.Z >= 5.4.0
import neo4j from 'https://unpkg.com/[email protected]/lib/browser/neo4j-web.esm.min.js'

// jsDelivr CDN non-minified, version X.Y.Z where X.Y.Z >= 5.4.0
import neo4j from 'https://cdn.jsdelivr.net/npm/[email protected]/lib/browser/neo4j-web.esm.js'

// jsDelivr CDN minified for production use, version X.Y.Z where X.Y.Z >= 5.4.0
import neo4j from 'https://cdn.jsdelivr.net/npm/[email protected]/lib/browser/neo4j-web.esm.min.js'

It is not required to explicitly close the driver on a web page. Web browser should gracefully close all open WebSockets when the page is unloaded. However, driver instance should be explicitly closed when it's lifetime is not the same as the lifetime of the web page:

driver.close() // returns a Promise

Usage examples

Constructing a Driver

// Create a driver instance, for the user `neo4j` with password `password`.
// It should be enough to have a single driver per database per application.
var driver = neo4j.driver(
  'neo4j://localhost',
  neo4j.auth.basic('neo4j', 'password')
)

// Close the driver when application exits.
// This closes all used network connections.
await driver.close()

Acquiring a Session

Regular Session

// Create a session to run Cypher statements in.
// Note: Always make sure to close sessions when you are done using them!
var session = driver.session()
with a Default Access Mode of READ
var session = driver.session({ defaultAccessMode: neo4j.session.READ })
with Bookmarks
var session = driver.session({
  bookmarks: [bookmark1FromPreviousSession, bookmark2FromPreviousSession]
})
against a Database
var session = driver.session({
  database: 'foo',
  defaultAccessMode: neo4j.session.WRITE
})

Reactive Session

// Create a reactive session to run Cypher statements in.
// Note: Always make sure to close sessions when you are done using them!
var rxSession = driver.rxSession()
with a Default Access Mode of READ
var rxSession = driver.rxSession({ defaultAccessMode: neo4j.session.READ })
with Bookmarks
var rxSession = driver.rxSession({
  bookmarks: [bookmark1FromPreviousSession, bookmark2FromPreviousSession]
})
against a Database
var rxSession = driver.rxSession({
  database: 'foo',
  defaultAccessMode: neo4j.session.WRITE
})

Executing Queries

Consuming Records with Streaming API

// Run a Cypher statement, reading the result in a streaming manner as records arrive:
session
  .run('MERGE (alice:Person {name : $nameParam}) RETURN alice.name AS name', {
    nameParam: 'Alice'
  })
  .subscribe({
    onKeys: keys => {
      console.log(keys)
    },
    onNext: record => {
      console.log(record.get('name'))
    },
    onCompleted: () => {
      session.close() // returns a Promise
    },
    onError: error => {
      console.log(error)
    }
  })

Subscriber API allows following combinations of onKeys, onNext, onCompleted and onError callback invocations:

  • zero or one onKeys,
  • zero or more onNext followed by onCompleted when operation was successful. onError will not be invoked in this case
  • zero or more onNext followed by onError when operation failed. Callback onError might be invoked after couple onNext invocations because records are streamed lazily by the database. onCompleted will not be invoked in this case.

Consuming Records with Promise API

// the Promise way, where the complete result is collected before we act on it:
session
  .run('MERGE (james:Person {name : $nameParam}) RETURN james.name AS name', {
    nameParam: 'James'
  })
  .then(result => {
    result.records.forEach(record => {
      console.log(record.get('name'))
    })
  })
  .catch(error => {
    console.log(error)
  })
  .then(() => session.close())

Consuming Records with Reactive API

rxSession
  .run('MERGE (james:Person {name: $nameParam}) RETURN james.name AS name', {
    nameParam: 'Bob'
  })
  .records()
  .pipe(
    map(record => record.get('name')),
    concatWith(rxSession.close())
  )
  .subscribe({
    next: data => console.log(data),
    complete: () => console.log('completed'),
    error: err => console.log(err)
  })

Transaction functions

// Transaction functions provide a convenient API with minimal boilerplate and
// retries on network fluctuations and transient errors. Maximum retry time is
// configured on the driver level and is 30 seconds by default:
// Applies both to standard and reactive sessions.
neo4j.driver('neo4j://localhost', neo4j.auth.basic('neo4j', 'password'), {
  maxTransactionRetryTime: 30000
})

Reading with Async Session

// It is possible to execute read transactions that will benefit from automatic
// retries on both single instance ('bolt' URI scheme) and Causal Cluster
// ('neo4j' URI scheme) and will get automatic load balancing in cluster deployments
var readTxResultPromise = session.readTransaction(txc => {
  // used transaction will be committed automatically, no need for explicit commit/rollback

  var result = txc.run('MATCH (person:Person) RETURN person.name AS name')
  // at this point it is possible to either return the result or process it and return the
  // result of processing it is also possible to run more statements in the same transaction
  return result
})

// returned Promise can be later consumed like this:
readTxResultPromise
  .then(result => {
    console.log(result.records)
  })
  .catch(error => {
    console.log(error)
  })
  .then(() => session.close())

Reading with Reactive Session

rxSession
  .readTransaction(txc =>
    txc
      .run('MATCH (person:Person) RETURN person.name AS name')
      .records()
      .pipe(map(record => record.get('name')))
  )
  .subscribe({
    next: data => console.log(data),
    complete: () => console.log('completed'),
    error: err => console.log(error)
  })

Writing with Async Session

// It is possible to execute write transactions that will benefit from automatic retries
// on both single instance ('bolt' URI scheme) and Causal Cluster ('neo4j' URI scheme)
var writeTxResultPromise = session.writeTransaction(async txc => {
  // used transaction will be committed automatically, no need for explicit commit/rollback

  var result = await txc.run(
    "MERGE (alice:Person {name : 'Alice'}) RETURN alice.name AS name"
  )
  // at this point it is possible to either return the result or process it and return the
  // result of processing it is also possible to run more statements in the same transaction
  return result.records.map(record => record.get('name'))
})

// returned Promise can be later consumed like this:
writeTxResultPromise
  .then(namesArray => {
    console.log(namesArray)
  })
  .catch(error => {
    console.log(error)
  })
  .then(() => session.close())

Writing with Reactive Session

rxSession
  .writeTransaction(txc =>
    txc
      .run("MERGE (alice:Person {name: 'James'}) RETURN alice.name AS name")
      .records()
      .pipe(map(record => record.get('name')))
  )
  .subscribe({
    next: data => console.log(data),
    complete: () => console.log('completed'),
    error: error => console.log(error)
  })

Explicit Transactions

With Async Session

// run statement in a transaction
const txc = session.beginTransaction()
try {
  const result1 = await txc.run(
    'MERGE (bob:Person {name: $nameParam}) RETURN bob.name AS name',
    {
      nameParam: 'Bob'
    }
  )
  result1.records.forEach(r => console.log(r.get('name')))
  console.log('First query completed')

  const result2 = await txc.run(
    'MERGE (adam:Person {name: $nameParam}) RETURN adam.name AS name',
    {
      nameParam: 'Adam'
    }
  )
  result2.records.forEach(r => console.log(r.get('name')))
  console.log('Second query completed')

  await txc.commit()
  console.log('committed')
} catch (error) {
  console.log(error)
  await txc.rollback()
  console.log('rolled back')
} finally {
  await session.close()
}

With Reactive Session

rxSession
  .beginTransaction()
  .pipe(
    mergeMap(txc =>
      concatWith(
        txc
          .run(
            'MERGE (bob:Person {name: $nameParam}) RETURN bob.name AS name',
            {
              nameParam: 'Bob'
            }
          )
          .records()
          .pipe(map(r => r.get('name'))),
        of('First query completed'),
        txc
          .run(
            'MERGE (adam:Person {name: $nameParam}) RETURN adam.name AS name',
            {
              nameParam: 'Adam'
            }
          )
          .records()
          .pipe(map(r => r.get('name'))),
        of('Second query completed'),
        txc.commit(),
        of('committed')
      ).pipe(catchError(err => txc.rollback().pipe(throwError(() => err))))
    )
  )
  .subscribe({
    next: data => console.log(data),
    complete: () => console.log('completed'),
    error: error => console.log(error)
  })

Numbers and the Integer type

The Neo4j type system uses 64-bit signed integer values. The range of values is between -(264- 1) and (263- 1).

However, JavaScript can only safely represent integers between Number.MIN_SAFE_INTEGER -(253- 1) and Number.MAX_SAFE_INTEGER (253- 1).

In order to support the full Neo4j type system, the driver will not automatically convert to javascript integers. Any time the driver receives an integer value from Neo4j, it will be represented with an internal integer type by the driver.

Any javascript number value passed as a parameter will be recognized as Float type.

Writing integers

Numbers written directly e.g. session.run("CREATE (n:Node {age: $age})", {age: 22}) will be of type Float in Neo4j.

To write the age as an integer the neo4j.int method should be used:

var neo4j = require('neo4j-driver')

session.run('CREATE (n {age: $myIntParam})', { myIntParam: neo4j.int(22) })

To write an integer value that are not within the range of Number.MIN_SAFE_INTEGER -(253- 1) and Number.MAX_SAFE_INTEGER (253- 1), use a string argument to neo4j.int:

session.run('CREATE (n {age: $myIntParam})', {
  myIntParam: neo4j.int('9223372036854775807')
})

Reading integers

In Neo4j, the type Integer can be larger what can be represented safely as an integer with JavaScript Number.

It is only safe to convert to a JavaScript Number if you know that the number will be in the range Number.MIN_SAFE_INTEGER -(253- 1) and Number.MAX_SAFE_INTEGER (253- 1).

In order to facilitate working with integers the driver include neo4j.isInt, neo4j.integer.inSafeRange, neo4j.integer.toNumber, and neo4j.integer.toString.

var smallInteger = neo4j.int(123)
if (neo4j.integer.inSafeRange(smallInteger)) {
  var aNumber = smallInteger.toNumber()
}

If you will be handling integers that is not within the JavaScript safe range of integers, you should convert the value to a string:

var largeInteger = neo4j.int('9223372036854775807')
if (!neo4j.integer.inSafeRange(largeInteger)) {
  var integerAsString = largeInteger.toString()
}

Enabling native numbers

Starting from 1.6 version of the driver it is possible to configure it to only return native numbers instead of custom Integer objects. The configuration option affects all integers returned by the driver. Enabling this option can result in a loss of precision and incorrect numeric values being returned if the database contains integer numbers outside of the range [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]. To enable potentially lossy integer values use the driver's configuration object:

var driver = neo4j.driver(
  'neo4j://localhost',
  neo4j.auth.basic('neo4j', 'password'),
  { disableLosslessIntegers: true }
)

neo4j-javascript-driver's People

Contributors

ali-ince avatar bigmontz avatar boggle avatar bradenmacdonald avatar conorneo avatar eve-bright avatar fbiville avatar jakewins avatar johnymontana avatar joknelid avatar jsoref avatar lutovich avatar martin-neotech avatar nigelsmall avatar oskarhane avatar parzhitsky avatar pocesar avatar pontusmelke avatar praveenag avatar ragnarw avatar robsdedude avatar slapersonne avatar stefano-ottolenghi avatar stephencathcart avatar technige avatar thebestnom avatar thelonelyvulpes avatar timothymischief avatar whatsocks avatar zhenlineo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

neo4j-javascript-driver's Issues

Transaction support

How does work transactions in this new version ?
This driver already support transactions or will support ?
I'm question about that because transactions is always a weak point in every neo4j driver in javascript. I already saw some driver that have support (in version 2), but it's very poor compared with Java or other javascript options like sequelize (what is a orm, but do the job very well).

how to specific the port for driver?

When using docker, neo4j may have port 10452 or so, not conventional 7474,
and the database may use ip 192.168.99.100.

So should I use this?:

const driver = neo4j.driver('bolt://' + hostname + ':' + port , neo4j.auth.basic(userName, passWord));

What I tested out is that bolt://192.168.99.100 is OK when docker is running at 192.168.99.100, but 192.168.99.100:7474 is not working. So there is no way to a specific port?

And, should I always end the session using session.close() after something ?
I doubt I can use one session for the entire run time, and don't even close manually. Will it be automatically closed?

Thanks!

onNext and onError being triggered on transaction deadlocks

Hello,

I am running into an issue with doing lots of async merge queries. Every now and then I hit a transaction deadlock (code 127). When this happens it seems that both onNext and onError are being triggered.

The main issue is I am using a callback both in onNext and onError:

session
          .run(query, params)
          .subscribe({
            onNext: (record) => callback(null, record.get('c.id')),
            onCompleted: () => session.close(),
            onError: (err) => callback(err),
          });

And node crashes with both callbacks are called.

Parameter field not correctly placed in query

Parameter field not correctly placed in query

I have some trouble querying with a paramenter of type int. Here’s the query itself:

"MATCH (n:NodeTypeOne)-->(m:NodeTimeTwo) WHERE ID(m) = {id} RETURN n"

And this is the parameter object given to the run statement:

{id: 2210} //where 2210 is an int

The run statement get’s called as such:

this.driver.session().run("MATCH (n:NodeTypeOne)-->(m:NodeTimeTwo) WHERE ID(m) = {id} RETURN n", {id: id})

To me, this seems correct as I’ve done it countless times this way. Yet I must be overlooking something since I get an error 127 response telling me there is a syntax error somewhere. When I replace the {id} with 2210 in the actual query, everything works as expected.

Is there something I’m missing here?

known_host host identity fingerprint duplication

Referring to issue #107
I have looked through the code and found that the only way that this error can happen

/app/node_modules/neo4j-driver/lib/v1/internal/ch-node.js:214
      for (var i = 0; i < pending.length; i++) {
                                 ^

TypeError: Cannot read property 'length' of null
    at /app/node_modules/neo4j-driver/lib/v1/internal/ch-node.js:214:34
    ...

is if the trust certificate callback is called twice:

    this._handleConnectionError = this._handleConnectionError.bind(this);

-> this._conn = connect(opts, function () {
      if (!self._open) {
        return;
      }

     <...>
      var pending = self._pending;
      self._pending = null;
      for (var i = 0; i < pending.length; i++) {
        self.write(pending[i]);
      }
    }, this._handleConnectionError);

because it it setting self._pending to be null.

The trust certificate function can be called twice if the loadFingerprint callback is called twice.
After looking at the known_hosts file

localhost:7687 fabacd62dbd94...
localhost:7687 fabacd62dbd94...

We see that there are duplicate entries, causing this to fire more than once:

require('readline').createInterface({
    input: fs.createReadStream(knownHostsPath)
  }).on('line', (line)  => {
    if( line.startsWith( serverId )) {
-->   found = true;
-->   cb( line.split(" ")[1] );
    }
  }).on('close', () => {
    if(!found) {
      cb(null);
    }
  });

But why are there duplicates?
Under the circumstances that the known_hosts file exists but is empty (manually created by someone) and if the app is calling for two (or more) driver sessions in the same process tick

const session = driver.session();
const session2 = driver.session();

The driver doesn't have time to update the known_hosts file and thus creates two (or more) entries of the same thing.
After that, the next session that is created:

setTimeout(() => {
    const session3 = driver.session();
}, 1000);

will throw the error.

Don't know how to decode strings from CombinedBuffer

Just to record this somewhere, this popped up when playing with the driver today, I guess we need to sort out being able to decode utf-8 when it's split into chunks;

Error: Don't know how to decode strings from `CombinedBuffer( position=6 )
  b1 71 91 b3 4e 89 6e 6f 64 65 2f 32 36 38 31 91 86 54 49 43 4b 45 54 a1 82 69 64 c9 00 9c `.
    at Object.decode (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/utf8.js:37:17)
    at Unpacker.unpack (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/packstream.js:366:34)
    at node (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/connector.js:132:54)
    at Unpacker.unpackStruct (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/packstream.js:305:16)
    at Unpacker.unpack (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/packstream.js:372:21)
    at Unpacker.unpackList (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/packstream.js:285:25)
    at Unpacker.unpack (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/packstream.js:368:21)
    at Unpacker.unpackStruct (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/packstream.js:309:34)
    at Unpacker.unpack (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/packstream.js:372:21)
    at Dechunker.Connection._dechunker.onmessage (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/connector.js:250:42)
    at Dechunker._onHeader (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/chunking.js:214:14)
    at Dechunker.AWAITING_CHUNK (/Users/jake/Code/neo4j-javascript-driver/build/node/internal/chunking.js:163:21)

Neo4J 3.0 overlapping transactions

I am using Neo4j v3.0.6 with neo4j-driver 1.1.0-M2 (BOLT) and am experiencing the following behaviour where everytime two transactions overlap the second one fails. Is that expected behaviour? It looks weird to me given they are also in different session and they access different data.

session1 = db.session()
txn1 = session1.beginTransaction()
session2 = db.session()
txn2 = session2.beginTransaction()
txn1.commit()
txn2.commit() -> Fails with signature 126 and no other message

See also: http://stackoverflow.com/questions/39846438/neo4j-3-0-overlapping-transactions

Session is lost when Neo4j is restarted

With version 1.0.4, the driver does not reconnect when the server closes its connection. This is an important issue because we have to reinitialize the session if we restart the Neo4j server.

Is it possible to create a new Bolt connection when the current one is lost?

The issue can be reproduced with the following script:

const neo4j = require("neo4j-driver").v1;
const spawn = require("child_process").spawn;
const Socket = require("net").Socket;

var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"));
var session = driver.session();

function waitPort(port, next) {

  var client = new Socket();
  client.on("error", function() {
    setTimeout(function() { waitPort(port, next) }, 300);
  });

  client.connect(port, "localhost", next);

}

// 1) Execute a query

session
  .run("RETURN 1")
  .subscribe({
    onCompleted: function() {},
    onNext: function(record) {

      console.log("Got a record; Restart Neo4j");

      // 2) Restart Neo4j

      spawn("./neo4j-community-3.0.6/bin/neo4j", [ "restart" ])
        .on("close", function() {

          // 3) When Neo4j is ready, execute the next query

          waitPort(7687, function() {

            console.log("Bolt is ready to be used; driver should be able to reconnect");

            session
              .run("RETURN 1")
              .subscribe({
                onCompleted: function() {},

                onNext: function(record) {
                  console.log("It works!");
                }
              });

          });

      })
    }
  })

This script produces the following output:

Got a record; Restart Neo4j
Bolt is ready to be used; driver should be able to reconnect
Uncaught error when processing result: Error: This socket has been ended by the other party

npm test fail

I'm running 3.0.0-RC1 on localhost on a mac
node v5.10.1 / npm 3.8.3 (latest stable from nvm)

➜  neo4j-javascript-driver git:(1.1) npm test

> [email protected] test /Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver
> gulp test

[11:30:50] Using gulpfile ~/Documents/_projects/TSL/neo4j-javascript-driver/gulpfile.js
[11:30:50] Starting 'test'...
[11:30:50] Starting 'nodejs'...
[11:30:53] Finished 'nodejs' after 2.5 s
[11:30:53] Starting 'test-nodejs'...
.............................F....................................................................................

Failures:
1) trust-signed-certificates should accept known certificates
1.1) Error: ENOENT: no such file or directory, open 'build/neo4j-enterprise-3.1.0/certificates/neo4j.cert'
    Error: ENOENT: no such file or directory, open 'build/neo4j-enterprise-3.1.0/certificates/neo4j.cert'
        at Error (native)
        at Object.fs.openSync (fs.js:584:18)
        at fs.readFileSync (fs.js:431:33)
        at Array.map (native)
        at Object.TRUST_SIGNED_CERTIFICATES (/Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/lib/v1/internal/ch-node.js:97:36)
        at connect (/Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/lib/v1/internal/ch-node.js:161:37)
        at new NodeChannel (/Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/lib/v1/internal/ch-node.js:194:18)
        at connect (/Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/lib/v1/internal/connector.js:474:25)
        at Driver._createConnection (/Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/lib/v1/driver.js:101:49)
        at Pool.acquire (/Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/lib/v1/internal/pool.js:69:21)

114 specs, 1 failure
Finished in 4.6 seconds
[11:30:58] 'test-nodejs' errored after 4.71 s
[11:30:58] Error in plugin 'gulp-jasmine'
Message:
    Tests failed
[11:30:58] 'test' errored after 7.21 s
[11:30:58] Error in plugin 'run-sequence'
Message:
    An error occured in task 'test-nodejs'.
npm ERR! Test failed.  See above for more details.

tried again with ./runTests.sh

➜  neo4j-javascript-driver git:(1.1) ✗ ./runTests.sh

> [email protected] start-neo4j /Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver
> gulp start-neo4j

[11:32:46] Using gulpfile ~/Documents/_projects/TSL/neo4j-javascript-driver/gulpfile.js
[11:32:46] Starting 'download-neo4j'...
[gulp] Downloading http://alpha.neohq.net/dist/neo4j-enterprise-3.1.0-NIGHTLY-unix.tar.gz... undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% undefined% Done
[11:33:49] Finished 'download-neo4j' after 1.05 min
[11:33:49] Starting 'set-password'...
[11:33:50] Finished 'set-password' after 139 ms
[11:33:50] Starting 'start-neo4j'...
Starting Neo4j.
Started neo4j (pid 58248). By default, it is available at http://localhost:7474/
There may be a short delay until the server is ready.
See /Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/build/neo4j-enterprise-3.1.0/logs/neo4j.log for current status.
[11:33:50] Finished 'start-neo4j' after 556 ms

> [email protected] test /Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver
> gulp test

[11:33:54] Using gulpfile ~/Documents/_projects/TSL/neo4j-javascript-driver/gulpfile.js
[11:33:54] Starting 'test'...
[11:33:54] Starting 'nodejs'...
[11:33:56] Finished 'nodejs' after 2.49 s
[11:33:56] Starting 'test-nodejs'...
.............................F...............................................F....................................

Failures:
1) trust-signed-certificates should accept known certificates
1.1) Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
    Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
        at Timeout._onTimeout (/Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1909:23)
        at tryOnTimeout (timers.js:224:11)
        at Timer.listOnTimeout (timers.js:198:5)

2) transaction should handle failures with subscribe
2.1) Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
    Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
        at Timeout._onTimeout (/Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1909:23)
        at tryOnTimeout (timers.js:224:11)
        at Timer.listOnTimeout (timers.js:198:5)

114 specs, 2 failures
Finished in 18 seconds
[11:34:15] 'test-nodejs' errored after 18 s
[11:34:15] Error in plugin 'gulp-jasmine'
Message:
    Tests failed
[11:34:15] 'test' errored after 21 s
[11:34:15] Error in plugin 'run-sequence'
Message:
    An error occured in task 'test-nodejs'.
npm ERR! Test failed.  See above for more details.

> [email protected] stop-neo4j /Users/cristina/Documents/_projects/TSL/neo4j-javascript-driver
> gulp stop-neo4j

[11:34:18] Using gulpfile ~/Documents/_projects/TSL/neo4j-javascript-driver/gulpfile.js
[11:34:18] Starting 'stop-neo4j'...
Neo4j not running
[11:34:18] Finished 'stop-neo4j' after 290 ms

Known hosts error

I keep getting a knownHosts error on boot. Is this just a warning that the directory doesnt exists and that its being created? Is this a folder we can create ourselves? Or am I missing something?

Driver:

var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver(_URI_, neo4j.auth.basic(_USER_, _PASS_), {
    trust: 'TRUST_ON_FIRST_USE',
    encrypted: true
});
var session = driver.session();

Error:

[Error: ENOENT: no such file or directory, open '/app/.neo4j/known_hosts']
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/app/.neo4j/known_hosts'

Running:

node: 4.4.5
npm: 2.15.5
neo4j: 3.0.2
neo4j-driver: 1.0.2

Setting for returning strings by default instead of neo4j.int

Currently the API returns neo4j.int instances for every numeric result. Converting these to strings before sending it to the user is quite tedious. I was wondering if a default 'string' setting would make sense, this would alleviate a lot of unnecessary mapping.

Rollback calls failing silently after invalid pack error

When rolling back after this root error:

Cannot pack this value: undefined

the promise fails to reject or resolve:

      return tx.rollback()
        .then(() => {
          console.log('resolve!');
          session.close();
          operations = tx = session = undefined;
        },
        (err) => {
          console.log('reject!', err);
          session.close();
          operations = tx = session = undefined;

          log(['error', 'neo', 'transaction', 'rollback'], {sourceId, transactionId, error: err.stack});
          return Promise.reject(err);
        });

Trying to log through this a bit, I found the following:

packStruct 10
Error
    at Packer.packStruct (~/node_modules/neo4j-driver/lib/v1/internal/packstream.js:160:21)
    at Connection.run (~/node_modules/neo4j-driver/lib/v1/internal/connector.js:384:20)
    at _runDiscardAll (~/node_modules/neo4j-driver/lib/v1/transaction.js:236:8)
    at Object.rollback (~/node_modules/neo4j-driver/lib/v1/transaction.js:168:24)
    at Transaction.rollback (~/node_modules/neo4j-driver/lib/v1/transaction.js:115:35)
    at Object.rollback (~/src/neo4j.js:144:25)
    at ~/src/neo4j.js:103:31
    at lib$es6$promise$$internal$$tryCatch (~/node_modules/neo4j-driver/lib/external/es6-promise.js:338:14)
    at lib$es6$promise$$internal$$invokeCallback (~/node_modules/neo4j-driver/lib/external/es6-promise.js:353:15)
    at lib$es6$promise$$internal$$publish (~/node_modules/neo4j-driver/lib/external/es6-promise.js:321:9)
    at lib$es6$promise$$internal$$publishRejection (~/node_modules/neo4j-driver/lib/external/es6-promise.js:263:5)
    at lib$es6$promise$asap$$flush (~/node_modules/neo4j-driver/lib/external/es6-promise.js:120:7)
    at doNTCallback0 (node.js:430:9)
    at process._tickDomainCallback (node.js:400:13)
pack ROLLBACK string
pack {} object
packStruct 2f

To which the server responded:

message! Structure { signature: 112, fields: [ { fields: [] } ] }
message! Structure { signature: 112, fields: [ {} ] }
message! Structure {
  signature: 127,
  fields:
   [ { code: 'Neo.ClientError.Request.InvalidFormat',
       message: 'Unknown struct type: 10' } ] }

Client Instance:

$ node --version
v5.1.1
$ npm ls | grep neo
├── [email protected]

Database Instance:

neo4j:
  container_name: neo4j
  image: neo4j:3.0.2-enterprise
  ports:
    - "7474:7474"
    - "7687:7687"

So after all of that, my concerns are:

  1. It seems that the pack algorithm blows up when undefined is passed in a parameters object. It seems like this should silently ignore this case.
  2. I fear that there are other possible cases that error handling can fail when using the promises form of requests.

TypeError: this.getFloat64 is not a function

I put this here to have it documented somewhere.

/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/buf.js:273
      return this.getFloat64(this._updatePos(8));
                  ^

TypeError: this.getFloat64 is not a function
    at CombinedBuffer.readFloat64 (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/buf.js:273:19)
    at Unpacker.unpack (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/packstream.js:344:23)
    at Unpacker.unpackList (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/packstream.js:304:25)
    at Unpacker.unpack (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/packstream.js:387:21)
    at Unpacker.unpackStruct (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/packstream.js:328:34)
    at Unpacker.unpack (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/packstream.js:391:21)
    at Dechunker.Connection._dechunker.onmessage (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/connector.js:231:42)
    at Dechunker._onHeader (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/chunking.js:235:14)
    at Dechunker.AWAITING_CHUNK (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/chunking.js:184:21)
    at Dechunker.write (/Users/oskarhane/Development/neo4j-javascript-driver/build/node/internal/chunking.js:246:28)

Reproduce: Execute this cypher 'UNWIND RANGE(0, 1000) AS num RETURN toFloat(num) AS x'

Documentation clarification about database version

Hello,

I installed the neo4j-driver with npm install neo4j-driver but I have been unsuccessful in getting any response back from the server. I later discovered that this was due to the fact that the Neo4j version was 3.0.0-M02. Everything seems to work just fine after installing 3.0.0-M01 on the server.

It would be very nice to see this in the documentation so that people don't struggle to find what the problem is.

One thing that bugs me is that the included tests seem to pass when I run them after cding into node_modules/neo4j-driver. I can't for the life of me explain why that would be.

This seems to be a problem with the Python driver as well, should I open an issue over that repo as well?

I would be more than happy to submit a PR for this, if that suits you.

Kind regards,

Can

Huge increase of open filedescriptors

  • Neo4j version: 3.0.1
  • Language: Javascript (NodeJS v4.4.4)
  • OS: Ubuntu 14.04.3 LTS
  • Single Machine

Hello,

I have one machine running neo4j and another one running a node process.
I'm using neo4j-driver 1.0.1.
When neo4j throws a OOM exception and the node process tries to open a session to this instance, the machine running nodejs runs out of file-descriptors.
counting the open files to the neo4j instance shows numbers around the 30000.

Is there a way to limit the connections of the neo4j driver?

Many thanks in advance!

Timo

Errors in Angular 2 CLI importing

Helloes,
I'm having some module not found errors while trying to use Neo4j driver in my Angular 2 CLI app.

I might be missing something trying to import it.

  • I installed it with: ng install neo4j-driver
  • In my service.ts: import 'neo4j-driver/lib/browser/neo4j-web';
  • Trying to call this example code in the service:
getFromDB(): void {
    var neo4j = require('neo4j-driver').v1;
    var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "password"));

    // Create a session to run Cypher statements in.
    // Note: Always make sure to close sessions when you are done using them!
    var session = driver.session();

    // Run a Cypher statement, reading the result in a streaming manner as records arrive:
    session
      .run("OPTIONAL MATCH (source)-[r]-(target) WHERE r is not null RETURN (source)")
      .subscribe({
        onNext: function (record) {
          console.log(record._fields);
        },
        onCompleted: function () {
          // Completed!
          session.close();
        },
        onError: function (error) {
          console.log(error);
        }
      });
  }

When I ng serve my application, I get the following errors:

ERROR in ./~/neo4j-driver/lib/v1/internal/ch-node.js
Module not found: Error: Can't resolve 'net' in 'E:\emek\node_modules\neo4j-driver\lib\v1\internal'
 @ ./~/neo4j-driver/lib/v1/internal/ch-node.js 32:11-25 364:2-24
 @ ./~/neo4j-driver/lib/v1/internal/connector.js
 @ ./~/neo4j-driver/lib/v1/driver.js
 @ ./~/neo4j-driver/lib/v1/index.js
 @ ./~/neo4j-driver/lib/index.js
 @ ./src/app/services/heroes.service.ts
 @ ./src/app/app.component.ts
 @ ./src/app/index.ts
 @ ./src/main.ts
 @ multi main
ERROR in ./~/neo4j-driver/lib/v1/internal/ch-node.js
Module not found: Error: Can't resolve 'tls' in 'E:\emek\node_modules\neo4j-driver\lib\v1\internal'
 @ ./~/neo4j-driver/lib/v1/internal/ch-node.js 36:11-25
 @ ./~/neo4j-driver/lib/v1/internal/connector.js
 @ ./~/neo4j-driver/lib/v1/driver.js
 @ ./~/neo4j-driver/lib/v1/index.js
 @ ./~/neo4j-driver/lib/index.js
 @ ./src/app/services/heroes.service.ts
 @ ./src/app/app.component.ts
 @ ./src/app/index.ts
 @ ./src/main.ts
 @ multi main
ERROR in ./~/neo4j-driver/lib/v1/internal/ch-node.js
Module not found: Error: Can't resolve 'readline' in 'E:\emek\node_modules\neo4j-driver\lib\v1\internal'
 @ ./~/neo4j-driver/lib/v1/internal/ch-node.js 92:2-21
 @ ./~/neo4j-driver/lib/v1/internal/connector.js
 @ ./~/neo4j-driver/lib/v1/driver.js
 @ ./~/neo4j-driver/lib/v1/index.js
 @ ./~/neo4j-driver/lib/index.js
 @ ./src/app/services/heroes.service.ts
 @ ./src/app/app.component.ts
 @ ./src/app/index.ts
 @ ./src/main.ts
 @ multi main

angular-cli: 1.0.0-beta.15
node: 4.5.0
os: win32 x64

Cannot read property 'length' of null

$ cat test.js 
var neo4j = require('neo4j-driver').v1;

var driver = neo4j.driver("bolt://localhost");
// Create a session to run Cypher statements in.
// Note: Always make sure to close sessions when you are done using them!
var session = driver.session();

// Run a Cypher statement, reading the result in a streaming manner as records arrive:
session
  .run("MERGE (alice:Person {name : {nameParam} }) RETURN alice.name", { nameParam:'Alice' })
  .subscribe({
    onNext: function(record) {
     console.log(record._fields);
    },
    onCompleted: function() {
      // Completed!
      session.close();
    },
    onError: function(error) {
      console.log(error);
    }
  });


$ node test.js 
.../neo4j-driver/lib/v1/internal/ch-node.js:214
      for (var i = 0; i < pending.length; i++) {
                                 ^

TypeError: Cannot read property 'length' of null
    at .../neo4j-driver/lib/v1/internal/ch-node.js:214:34
    at .../neo4j-driver/lib/v1/internal/ch-node.js:141:11
    at Interface.<anonymous> (.../neo4j-driver/lib/v1/internal/ch-node.js:76:7)
    at emitOne (events.js:77:13)
    at Interface.emit (events.js:169:7)
    at Interface._onLine (readline.js:210:10)
    at Interface.<anonymous> (readline.js:340:12)
    at Array.forEach (native)
    at Interface._normalWrite (readline.js:339:11)
    at ReadStream.ondata (readline.js:86:10)

$ curl localhost:7474/db/data/
{
  "extensions" : { },
  "node" : "http://localhost:7474/db/data/node",
  "relationship" : "http://localhost:7474/db/data/relationship",
  "node_index" : "http://localhost:7474/db/data/index/node",
  "relationship_index" : "http://localhost:7474/db/data/index/relationship",
  "extensions_info" : "http://localhost:7474/db/data/ext",
  "relationship_types" : "http://localhost:7474/db/data/relationship/types",
  "batch" : "http://localhost:7474/db/data/batch",
  "cypher" : "http://localhost:7474/db/data/cypher",
  "indexes" : "http://localhost:7474/db/data/schema/index",
  "constraints" : "http://localhost:7474/db/data/schema/constraint",
  "transaction" : "http://localhost:7474/db/data/transaction",
  "node_labels" : "http://localhost:7474/db/data/labels",
  "neo4j_version" : "3.0.3"
}


neo4j.log

2016-07-26 23:06:26.534+0000 ERROR Client triggered an unexpected error [UnknownError]: null. See debug.log for more details, reference 70b41b21-9f53-42c2-b022-5d073f1ebd27.

debug.log

2016-07-26 23:12:42.571+0000 ERROR [o.n.b.v.t.BoltProtocolV1] Failed to write response to driver
java.lang.NullPointerException
        at org.neo4j.bolt.v1.transport.ChunkedOutput.ensure(ChunkedOutput.java:156)
        at org.neo4j.bolt.v1.transport.ChunkedOutput.writeShort(ChunkedOutput.java:90)
        at org.neo4j.bolt.v1.packstream.PackStream$Packer.packStructHeader(PackStream.java:304)
        at org.neo4j.bolt.v1.messaging.PackStreamMessageFormatV1$Writer.handleSuccessMessage(PackStreamMessageFormatV1.java:145)
        at org.neo4j.bolt.v1.messaging.msgprocess.MessageProcessingCallback.completed(MessageProcessingCallback.java:102)
        at org.neo4j.bolt.v1.messaging.msgprocess.MessageProcessingCallback.completed(MessageProcessingCallback.java:31)
        at org.neo4j.bolt.v1.runtime.internal.SessionStateMachine.after(SessionStateMachine.java:823)
        at org.neo4j.bolt.v1.runtime.internal.SessionStateMachine.pullAll(SessionStateMachine.java:666)
        at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorkerFacade.lambda$pullAll$4(SessionWorkerFacade.java:74)
        at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorkerFacade$$Lambda$173/1688248860.accept(Unknown Source)
        at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorker.execute(SessionWorker.java:116)
        at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorker.executeBatch(SessionWorker.java:102)
        at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorker.run(SessionWorker.java:82)
        at java.lang.Thread.run(Thread.java:745)

Multiple trustedCertificates throws error

For multiple trustedCertificates, e.g.
{trust: 'TRUST_SIGNED_CERTIFICATES', trustedCertificates: ['mycert.crt','intermediateca.crt','rootca.crt']}

Results in:
TypeError: Expected options to be either an object or a string, but got number instead at throwOptionsError (fs.js:75:9) at fs.readFileSync (fs.js:494:5) at Array.map (native) at Object.TRUST_SIGNED_CERTIFICATES (/Users/alexprice/nodejs/node_modules/neo4j-driver/lib/v1/internal/ch-node.js:101:36) at connect (/Users/alexprice/nodejs/node_modules/neo4j-driver/lib/v1/internal/ch-node.js:165:37) at new NodeChannel (/Users/alexprice/nodejs/node_modules/neo4j-driver/lib/v1/internal/ch-node.js:198:18) at connect (/Users/alexprice/nodejs/node_modules/neo4j-driver/lib/v1/internal/connector.js:489:25) at Driver._createConnection (/Users/alexprice/nodejs/node_modules/neo4j-driver/lib/v1/driver.js:101:49) at Pool.acquire (/Users/alexprice/nodejs/node_modules/neo4j-driver/lib/v1/internal/pool.js:69:21) at Driver.session (/Users/alexprice/nodejs/node_modules/neo4j-driver/lib/v1/driver.js:151:29)

In ch-node.js:
I changed this opts.trustedCertificates.map(_fs2['default'].readFileSync) to this opts.trustedCertificates.map(function(e) { return _fs2['default'].readFileSync(e); }).

Also, on an unrelated note, it would helpful to pass along the socket.authorizationError when !socket.authorized. This can be helpful when debugging TLS issues.

how to change password in neo4j 3.0 for travisCI test?

I used to write

  - curl -vX POST http://neo4j:neo4j@localhost:7474/user/neo4j/password -d"password=j4oen"

to change password for neo4j 2.3.2.

but for neo4j 3.0.0, travis returns

* About to connect() to localhost port 7474 (#0)
*   Trying 127.0.0.1... connected
* Server auth using Basic with user 'neo4j'
> POST /user/neo4j/password HTTP/1.1
> Authorization: Basic bmVvNGo6bmVvNGo=
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: localhost:7474
> Accept: */*
> Content-Length: 14
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 14out of 14 bytes
< HTTP/1.1 404 Not Found
< Access-Control-Allow-Origin: *
< Content-Type: text/html; charset=iso-8859-1
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Length: 1384
< Server: Jetty(6.1.25)
< 
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 404 Not Found</title>
</head>
<body><h2>HTTP ERROR 404</h2>
<p>Problem accessing /user/neo4j/password. Reason:
<pre>    Not Found</pre></p><hr /><i><small>Powered by Jetty://</small></i><br/>                                                
<br/>                                                                                            
</body>
</html>
* Connection #0 to host localhost left intact
* Closing connection #0

so what should I do now?

Internal error thrown during session.beginTransaction()

Version: 1.1.0-M01

var neo4j = require('neo4j-driver').v1;
var neo4jDriver = neo4j.driver("bolt://neo4j", neo4j.auth.basic("neo4j", "...."), {
    encrypted: false
});
var session = neo4jDriver.session();
var tx = session.beginTransaction();

gives this error:

TypeError: this._onClose is not a function
    at Transaction._onError (/srv/app/node_modules/neo4j-driver/lib/v1/transaction.js:124:12)
    at _TransactionStreamObserver.onError (/srv/app/node_modules/neo4j-driver/lib/v1/transaction.js:150:18)
    at Connection._queueObserver (/srv/app/node_modules/neo4j-driver/lib/v1/internal/connector.js:466:20)
    at Connection.run (/srv/app/node_modules/neo4j-driver/lib/v1/internal/connector.js:391:12)
    at new Transaction (/srv/app/node_modules/neo4j-driver/lib/v1/transaction.js:61:16)
    at Session.beginTransaction (/srv/app/node_modules/neo4j-driver/lib/v1/session.js:119:14)
    at repl:1:18
    at REPLServer.defaultEval (repl.js:252:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)

It turns out it is an error during an error. The initial error is that the connection to the database failed (wrong server hostname).

In general, are you supposed to run a test query on the database to know whether the connection was successfull?

Multiple session.run statements

I am not sure how to run multiple statements. For instance how could I create another constraint for user label ? Should I create a session again ?

const session = driver.session();
session
        .run("CREATE CONSTRAINT ON (user:USER) ASSERT user.email IS UNIQUE", {            nameParam:'Jamess' })
        .then((result) => {
            console.log("neo4j constraints successful");
            session.close();
        })
        .catch((error) => {
            console.log("constraint.js error : ",error);
        });

typescript definition file

Hi,

Is it possible to get a typescript definition file so this could be used in an Angular2 project?

Thanks

Alex

Checking if a value exists in a Record

There is no "proper" way to check if a value exists or not in a Record without trying to access and catching for errors.

Take this oversimplified example:

const queries = [
   'MATCH (a:Apple) RETURN COUNT(a) AS apples' ,
   'MATCH (a:Apple), (o:Orange) RETURN COUNT(a) AS apples, COUNT(o) AS oranges'
];

const query = queries[Math.random() > .5 ? 1 : 0];

session.run(query).then((data) => {
    console.log(data[0].get('apples'));

    // will throw if first query is chosen
    console.log(data[0].get('oranges')); 
});

There should be a way of checking for fields before trying to use them:

session.run(query).then((data) => {
    console.log(data[0].get('apples'));

    // will throw if first query is chosen
    if(data[0].has('oranges')) {
        console.log(data[0].get('oranges')); 
    }
});

Back pressure

Is there a way to apply back pressure to the driver if the consumer indicates they are not ready to receive a result?

My driver (cypher-stream) presents cypher results as Node.js object streams. Node streams support back pressure and high-watermark levels to allow fine-tuning of memory management. I'm curious if there's a way to implement this.

Equivalent of resultDataContents["graph"]

Is there any plans to include the REST equivalent of resultDataContents["graph"] in the Bolt implementation? Currently, getting data from bolt into something like linkurious requires you to coerce the returned data into the format expected by the graph. Would be useful to simplify the process of displaying the data in common formats, since translating the results of the REST call into the graph format is significantly easier.

Queries will hang arbitrarily

const getOneResult = transaction => {
    const session = driver.session();

    return session.run(transaction)
        .then(result => {

            session.close();
            return result;
        })
        .catch(err => { console.log(err); throw new Error('fail'); })
};

Occasionally, this will hang on session.run for a long period of time (~60 seconds?). After that, we get a ETIMEDOUT error. Hit that function again and it works fine, so it randomly seems to do this.

Connection pool returns terminated connections

From time to time, I see this message in the logs of my app.

Error: This socket has been ended by the other party
      at Socket.writeAfterFIN [as write] (net.js:286:12)
      at NodeChannel.write (.../node_modules/neo4j-driver/lib/v1/internal/ch-node.js:254:20)
      at Chunker.flush (.../node_modules/neo4j-driver/lib/v1/internal/chunking.js:114:18)
      at Connection.sync (.../node_modules/neo4j-driver/lib/v1/internal/connector.js:488:21)
      at Session._onClose (.../node_modules/neo4j-driver/lib/v1/driver.js:163:14)
      at Session.close (.../node_modules/neo4j-driver/lib/v1/session.js:138:16)
      at .../node_modules/seraph/lib/bolt/seraph.js:191:46
      at _treatParams.then.then.catch (.../node_modules/seraph/lib/bolt/seraph.js:260:31)
      at process._tickDomainCallback (internal/process/next_tick.js:129:7)

I am able to reproduce it by following these steps:

  1. Start neo4j and my app
  2. Make a request to my app, there is now one connection in the pool
  3. Restart the neo4j database
  4. Make another request to my app

To me, it seems like the connection pool is holding on to these connections that were closed by the server, i.e. the server sent a FIN packet to the socket. I have some code that fixes the issue for me, will submit a PR momentarily.

Websocket fails if data transmitted is over a certain size

Currently using the Papaparse library to parse out a CSV file and commit the data to a neo4j database.

The queries are created using an UNWIND syntax and props are created from the csv file directly. If I use a chunk size of anything greater than approximately 50000 bytes, the application will eventually cease to send any more data to neo4j. Note that, this issue does NOT exist in the node implementation, as the exact same code, copy pasted and run using node ./test.js works flawlessly.

The application is running in electron, so chromium based. No errors are emitted when the application stops sending data, and nothing is returned in the results. All queries are being done using promises.

var userQuery = 'UNWIND {props} AS prop MERGE (user:User {name:prop.account}) WITH user,prop MERGE (group:Group {name:prop.group}) WITH user,group MERGE (user)-[:MemberOf]->(group)'
var computerQuery = 'UNWIND {props} AS prop MERGE (computer:Computer {name:prop.account}) WITH computer,prop MERGE (group:Group {name:prop.group}) WITH computer,group MERGE (computer)-[:MemberOf]->(group)'
var groupQuery = 'UNWIND {props} AS prop MERGE (group1:Group {name:prop.account}) WITH group1,prop MERGE (group2:Group {name:prop.group}) WITH group1,group2 MERGE (group1)-[:MemberOf]->(group2)'
var s1 = driver.session()
var s2 = driver.session()
var s3 = driver.session()
console.log(s1)
console.log(s2)
console.log(s3)
var p1
var p2
var p3
p1 = s1.run(userQuery, {props: props.users})
p1.catch(function(err){
    console.log(err)
})
p1.then(function(){
    s1.close()
    p2 = s2.run(computerQuery, {props: props.computers})
    p2.catch(function(err){
        console.log(err)
    })
    p2.then(function(){
        s2.close()
        p3 = s3.run(groupQuery, {props: props.groups})
        p3.catch(function(err){
            console.log(err)
        })
        p3.then(function(){
            s3.close()
            this.setState({progress: Math.floor((sent / count) * 100)})
            console.log('set done')
            console.log(driver)
            parser.resume()
        }.bind(this))
    }.bind(this))
}.bind(this))

This is the relevant snippet of code. Depending on the size of the data chunk being submitted, this will either run a few times, or never at all.

Based on testing I've seen the following:
1MB of data will never submit anything
100kb of data will submit exactly twice
60kb of data will submit ~150 times and then fail
50kb of data will happily submit until my file is exhausted. It's entirely possible it would fail on a bigger file, which I'll test

Based on the behavior, by best guess is some sort of buffer being filled and then failing out, but I'm at a loss. The neo4j database log is similarly unenlightening.

Strange behavior with integer number literals being returned as objects {high: 23, low: 0}

package: "neo4j-driver": "^1.1.0-M01"
node: v6.2.1

I'm creating a new node in Neo4J using the following from NodeJS, noting that the property 'datapoints' is a number literal:

CREATE (a:pipeline)
    SET a.uuid       = {uuid},
        a.type       = "datasource",
        a.datapoints = 0,
        a.normalized = {normalized},
        a.headers    = {headers},
        a.types      = {types},
        a.t_created  = {now}
RETURN a

Now when I go to lookup that node using the following statement I get different results from the Neo4J browser and NodeJS driver:

MATCH (a:pipeline)
RETURN a

If I run this statement from the Neo4J browser I get a response as expected where datapoints is indeed a number:

{
  "records": [
    {
      "keys": [
        "a"
      ],
      "length": 1,
      "_fields": [
        {
          "identity": "37225",
          "labels": [
            "pipeline"
          ],
          "properties": {
            "headers": [
              "dt",
              "h"
            ],
            "datapoints": "0",
            "types": [
              "Date",
              "Float"
            ],
            "normalized": false,
            "type": "datasource",
            "t_created": 1472143439959,
            "uuid": "1472143439959.562064"
          },
          "id": "37225"
        }
      ],
      "_fieldLookup": {
        "a": 0
      }
    }
  ],
  "summary": {
    "statement": {
      "text": "MATCH (a:pipeline)\nRETURN a",
      "parameters": {}
    },
    "statementType": "r",
    "updateStatistics": {
      "_stats": {
        "nodesCreated": 0,
        "nodesDeleted": 0,
        "relationshipsCreated": 0,
        "relationshipsDeleted": 0,
        "propertiesSet": 0,
        "labelsAdded": 0,
        "labelsRemoved": 0,
        "indexesAdded": 0,
        "indexesRemoved": 0,
        "constraintsAdded": 0,
        "constraintsRemoved": 0
      }
    },
    "plan": false,
    "profile": false,
    "notifications": []
  },
  "responseTime": 316
}

However when I run the same statement using the NodeJS package I get an unexpected object for datapoints:

{
   "records": [
      {
         "keys": [
            "a"
         ],
         "length": 1,
         "_fields": [
            {
               "identity": {
                  "low": 37225,
                  "high": 0
               },
               "labels": [
                  "pipeline"
               ],
               "properties": {
                  "headers": [
                     "dt",
                     "h"
                  ],
                  "datapoints": {
                     "low": 0,
                     "high": 0
                  },
                  "types": [
                     "Date",
                     "Float"
                  ],
                  "normalized": false,
                  "type": "datasource",
                  "t_created": 1472143439959,
                  "uuid": "1472143439959.562064"
               }
            }
         ],
         "_fieldLookup": {
            "a": 0
         }
      }
   ],
   "summary": {
      "statement": {
         "text": "MATCH (a:pipeline)\r\nRETURN a",
         "parameters": {}
      },
      "statementType": "r",
      "updateStatistics": {
         "_stats": {
            "nodesCreated": 0,
            "nodesDeleted": 0,
            "relationshipsCreated": 0,
            "relationshipsDeleted": 0,
            "propertiesSet": 0,
            "labelsAdded": 0,
            "labelsRemoved": 0,
            "indexesAdded": 0,
            "indexesRemoved": 0,
            "constraintsAdded": 0,
            "constraintsRemoved": 0
         }
      },
      "plan": false,
      "profile": false,
      "notifications": []
   }
}

The result seems to be same for setting the property's value to any integer literal value, however setting the property's value to a floating point literal value (other than 0.0) behaves as expected:

{
   "records": [
      {
         "keys": [
            "a"
         ],
         "length": 1,
         "_fields": [
            {
               "identity": {
                  "low": 37253,
                  "high": 0
               },
               "labels": [
                  "pipeline"
               ],
               "properties": {
                  "headers": [
                     "dt",
                     "h"
                  ],
                  "datapoints": 0.1,
                  "types": [
                     "Date",
                     "Float"
                  ],
                  "normalized": false,
                  "type": "datasource",
                  "t_created": 1472143956047,
                  "uuid": "1472143956047.414768"
               }
            }
         ],
         "_fieldLookup": {
            "a": 0
         }
      }
   ],
   "summary": {
      "statement": {
         "text": "MATCH (a:pipeline)\r\nRETURN a",
         "parameters": {}
      },
      "statementType": "r",
      "updateStatistics": {
         "_stats": {
            "nodesCreated": 0,
            "nodesDeleted": 0,
            "relationshipsCreated": 0,
            "relationshipsDeleted": 0,
            "propertiesSet": 0,
            "labelsAdded": 0,
            "labelsRemoved": 0,
            "indexesAdded": 0,
            "indexesRemoved": 0,
            "constraintsAdded": 0,
            "constraintsRemoved": 0
         }
      },
      "plan": false,
      "profile": false,
      "notifications": []
   }
}

I considered that it may be the name of my property that was causing the issue, and can add that any property name is currently having this effect. Is this maybe the result of a database corruption?

Weird return value when returning more then 82 nodes

Hi all

I have 88 node labeled with Interest When trying to query to get all of them Im running the next query:

MATCH (interest:Interest)
return properties(interest) as interest

It looks like that when im getting the values one of the values looks like that:
selection_004

when running the same query via the browser all seems to work as expected.

Now if i take the query and run it with LIMIT 81 all still works but when the limit is more then 81 i get that weird node..

any ideas?

No operations allowed until you send an INIT message successfully

I'm getting this error but can't find any information except for the java file printing the error in the docs about this error.

Here's all my (ES 6) code:

import neo4j from 'neo4j-driver';

const neo4jv1 = neo4j.v1;
const driver = neo4jv1.driver('bolt://localhost', neo4jv1.auth.basic('neo4j', 'neo4j'));

const session = driver.session();
session.run('CREATE INDEX ON :Movie(id)')
  .then(function(result){
    console.log("result!");
    console.log(result);
    session.close();
    driver.close();
  })
  .catch(function(error) {
    console.log("error!");
    console.log(error);
    driver.close();
  });

And the output:

> [email protected] db-init /home/fliq/fliq-api
> node dist/scripts/init-db

error!
Structure {
  signature: 127,
  fields:
   [ { code: 'Neo.ClientError.Request.Invalid',
       message: 'No operations allowed until you send an INIT message successfully.' } ] }

Anyone seen this error before?

Intermittent error "This socket has been ended by the other party"

Hi, i'm connecting to my neo4j running on a docker container and i'm getting an error when i try to attempt to make another connection/query. The error is "This socket has been ended by the other party". This is my Dockerfile with the opened ports:

EXPOSE 7474 7473 7687

This is my driver utility:

var neo4j = require("neo4j-driver").v1,
    config = require("../../config");

(function(module){ 
    module.exports = function(){
        config.neo4j.server = 'localhost';
        return neo4j.driver("bolt://" + config.neo4j.server, neo4j.auth.basic(config.neo4j.user, config.neo4j.password));
    }
}(module));

The way i'm making my queries to neo4j:

(function(module){
    var driver = require('../../../utils/neo4j-driver')(),
        Q = require('q'),
        logger = require('../../../utils/logger'),
        BaseNeo4jModel = require('../../../utils/neo4j-model');

    function userDBAuth(user){
        var deferred = Q.defer();
        var session = driver.session();

        session
            //.run( "MATCH (a:Person) RETURN a.name AS name, a.uuid as uuid" )
            .run("MATCH (user:User {email:{email}})"
                    + "RETURN user",
                    { email: user.email})
            .then(function (result) {
                logger.debug('fetching results...');

                if(result.records.length > 0){
                    var records = [];

                    result.records.forEach(function(record){
                        records.push(new BaseNeo4jModel(record));
                    });

                    done();

                    deferred.resolve(records);
                } else {
                    deferred.reject({sucess: false, message: 'User not Found'});
                }

            }).catch( function(err) {
                logger.error(err);
                done();
                deferred.reject(err.fields[0]);
            });

            return deferred.promise;

        function done(){
            session.close();
            driver.close();
        }
    }

    module.exports = userDBAuth;

}(module));

And this is my stack trace:

{"name":"auth-services","hostname":"MacBook-Pro-de-Vinicius.local","pid":16292,"level":50,"err":{"message":"This socket has been ended by the other party","name":"Error","stack":"Error: This socket has been ended by the other party
at TLSSocket.writeAfterFIN [as write] (net.js:286:12)
at NodeChannel.write (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/neo4j-driver/lib/v1/internal/ch-node.js:285:20)
at Chunker.flush (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/neo4j-driver/lib/v1/internal/chunking.js:114:18)
at Connection.sync (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/neo4j-driver/lib/v1/internal/connector.js:487:21)
at Session.run (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/neo4j-driver/lib/v1/session.js:89:20)
at userDBAuth (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/app/api/auth/services/userDBAuth.js:13:7)
at Object._auth [as auth] (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/app/api/auth/services/auth.js:9:3)
at Server.auth (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/app/api/auth/resources/auth.js:7:12)
at next (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/restify/lib/server.js:906:30)
at f (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/once/once.js:25:25)","code":"EPIPE"},"msg":"This socket has been ended by the other party","time":"2016-09-27T11:12:33.163Z","v":0}

I'm desperate, please help me!

Inconsistent prerelease version number casing confuses npm

I noticed that some prerelease version numbers are lowercased (e.g., “-alpha.1”), and some are uppercased (e.g., “-M01” and “-RC1”).

This causes problems/confusion for node.js clients because npm, the node.js package manager, orders prerelease versions alphabetically (with uppercase letters coming before lowercase letters).

So, npm believes the alpha versions are more recent than the M and RC versions.

Can neo4j's node.js packages start using lowercasing for all prerelease version numbers, to avoid this in the future? If the possible prerelease version prefixes are, say (in order of freshness): "alpha", "beta", "m", and "rc", this would be a way to solve this issue.

For example, if the next RC version were to be "1.0.0-rc3", then npm would properly consider it (and not "1.0.0-alpha7") to be the highest prerelease version for 1.0.0.

Suggested feature: Make Node and Relationship classes public

Hello again,

I hope I'm not irritating you all with these issues.

One thing that I wish I had access to is the driver's internal types as defined in the graph-types.js file. Basically this would allow me to quickly determine the type of a result's parts. Granted, I can now check if the object has a start and an end field to determine that it is a Relationship but this is error prone and is heavily dependent on these classes implementation details. This may be very down the road, but I just wanted to leave a note of it here and perhaps hear your views on it.

Kind regards,

Can

Problem understanding scope of module (comment on the readme)

Hi!

I am searching for a high performance way to integrate Node.js and Neo4J. I am currently working on using node-java in combination with the native Java API for Neo4J. However, could this be a better alternative?

The readme makes me confused. It seems like a huge leap to go from node.js module to html directly. HTML is normally something for the client side. What I would like is just a javascript library for accessing a Neo4J database binary, just on the server. Could I see an example of that, without using any html?

Errors leaking to other queries on the same session

Having the following code:

var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver(
    'bolt://localhost',
    neo4j.auth.basic(
        'neo4j',
        'password'
    )
);

var session = driver.session();

session
    .run('bad query')
    .then(console.log)
    .catch(console.error);

session
    .run('return 1')
    .then(console.log)
    .catch(console.error);

will generate the following output

Structure {
  signature: 127,
  fields: 
   [ { code: 'Neo.ClientError.Statement.SyntaxError',
       message: 'Invalid input \'b\': expected <init> (line 1, column 1 (offset: 0))\n"bad query"\n ^' } ] }
Structure {
  signature: 127,
  fields: 
   [ { code: 'Neo.ClientError.Statement.SyntaxError',
       message: 'Invalid input \'b\': expected <init> (line 1, column 1 (offset: 0))\n"bad query"\n ^' } ] }

and the error seems to leak to the second query. Is this intended behaviour?

From my understanding, a session is a connection to the database, is it better to have one and run all the queries through it or have a different session for each and every query?

Note: the same effect will not happen if the first query has finished / errored before the start of the second query

UncaughtException when running a Cypher statement

Hello again,

During development, we have come across a bug that brings node to its knees. Apart from listening to node's uncaughtException event, we couldn't find a way of handling this. .catch() and onError for promise-based approach and subscribe() approach, respectively, do not work.

I have tried this against M01 and M02 with corresponding installs from npm. This is the case in both of them. I have started looking into packstream.js but honestly I don't have the heart for it before I learn how bolt packs its data first. I will definitely look into it more and will let you know if I come across something but I expect you guys will pinpoint the problem right away.

The Cypher statement works correctly against the REST API, so I don't think anything is wrong with the Cypher itself.

I have used the Movies dataset which I imported with :play movies on the included browser application.

This is on a new node/express project with only neo4j-driver install with npm install neo4j-driver. As I said both 1.0.0-M02 and 1.0.0-M01 releases are affected. I haven't tried 3.0.0-M03 DB version yet, because, well, I don't know which branch to install from this repository to test against that. I would appreciate if you could help me there.

On to the details!

var express = require('express');
var router = express.Router();
var n = require("neo4j-driver");

/* GET home page. */
router.get('/', function (req, res, next) {
  var driver = n.v1.driver("bolt://localhost:7687");
  var session = driver.session();
  session.run('match (k:`Person`) where id(k) = {idparam}\
    match p=(k)-[:ACTED_IN]-(m)\
    optional match p2= (k)-[:DIRECTED]-(c)\
  optional match p4= (m)-[:ACTED_IN]-()\
  optional match p5= (m)-[:DIRECTED]-() \
  return p,p2,p4,p5', {idparam: n.v1.int(71)}).subscribe({
    onNext     : function (record) {
      console.log(record);
    },
    onCompleted: function () {
      // Completed!
      session.close();
    },
    onError    : function (error) {
      console.log(error);
      res.send(error);
    }
  });
});

module.exports = router;

This is the only part that I have touched in the new project. This throws a TypeError with Cannot read property 'start' of undefined. The full stack is as follows:

  this.start = segments[0].start;
                          ^
TypeError: Cannot read property 'start' of undefined
    at new Path (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/graph-types.js:205:27)
    at path (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/connector.js:172:12)
    at Unpacker.unpackStruct (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/packstream.js:324:16)
    at Unpacker.unpack (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/packstream.js:391:21)
    at Unpacker.unpackList (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/packstream.js:304:25)
    at Unpacker.unpack (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/packstream.js:387:21)
    at Unpacker.unpackStruct (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/packstream.js:328:34)
    at Unpacker.unpack (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/packstream.js:391:21)
    at Dechunker.Connection._dechunker.onmessage (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/connector.js:240:42)
    at Dechunker._onHeader (/home/admins/Desktop/bolt/nodeTest/node_modules/neo4j-driver/lib/v1/internal/chunking.js:230:14)

Process finished with exit code 8

I hope this helps in recreating and fixing the issue. If there is any more information I can provide, please let me know. Anything I can look into myself, I'd be happy to if you could provide me with some pointers.

Kind regards,

Can

Promises swallowing syntax/runtime errors

Hey there,
I just noticed that the following code will throw but will swallow and not bubble up the error:

const session = driver.session();
session
    .run('return 1 as value')
    .catch(console.error)
    .then((data) => {
        if (data.records[0].get('value') % 2) {
            throw new Error('How odd!');
        }

        console.log('My awesome value is', data.records[0].get('value').toNumber())
    }, console.error);

and thus nothing will be displayed on the screen.

But when using subscribe, the errors are properly surfaced:

const session = driver.session();

session
    .run('return 1 as value')
    .subscribe({
        onError: console.error,
        onNext: (row) => {
            if (row.get('value') % 2) {
                throw new Error('How odd!');
            }

            console.log('My awesome value is', row.get('value').toNumber())
        },
        onCompleted: () => {
            console.log('I\'m done!');
            throw new Error('You should have closed the session dude 😱')
        }
    });

Both errors in onNext and onCompleted are surfaced.

Am I missing something here or is this intended behaviour?

NullPointerException when overflowing connectionPoolSize

Hi!

While I was writing unit tests for my app I noticed this exception when testing more concurrent sessions than connectionPoolSize in javascript neo4j-driver.

Versions:
neo4j - dockerized 3.0.1, image neo4j:3.0
neo4j-driver - tested on 1.0.1 and 1.0.4
nodejs - tested on 6.6.0 and 6.2.1

Error:

2016-09-27 19:21:41.296+0000 ERROR [o.n.b.v.t.BoltProtocolV1] Failed to write response to driver
java.lang.NullPointerException
    at org.neo4j.bolt.v1.transport.ChunkedOutput.ensure(ChunkedOutput.java:156)
    at org.neo4j.bolt.v1.transport.ChunkedOutput.writeShort(ChunkedOutput.java:90)
    at org.neo4j.bolt.v1.packstream.PackStream$Packer.packStructHeader(PackStream.java:304)
    at org.neo4j.bolt.v1.messaging.PackStreamMessageFormatV1$Writer.handleSuccessMessage(PackStreamMessageFormatV1.java:145)
    at org.neo4j.bolt.v1.messaging.msgprocess.MessageProcessingCallback.completed(MessageProcessingCallback.java:102)
    at org.neo4j.bolt.v1.messaging.msgprocess.MessageProcessingCallback.completed(MessageProcessingCallback.java:31)
    at org.neo4j.bolt.v1.runtime.internal.SessionStateMachine.after(SessionStateMachine.java:823)
    at org.neo4j.bolt.v1.runtime.internal.SessionStateMachine.reset(SessionStateMachine.java:699)
    at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorkerFacade.lambda$reset$6(SessionWorkerFacade.java:87)
    at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorker.execute(SessionWorker.java:116)
    at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorker.run(SessionWorker.java:77)
    at java.lang.Thread.run(Thread.java:745)

I can reproduce this error on fresh DB using this code:

const _ = require('lodash'),
      neo4j = require('neo4j-driver').v1;

const driver = neo4j.driver('bolt://localhost:7687',
                            neo4j.auth.basic('neo4j',
                                             'neo4j'),
                            {connectionPoolSize: 1});

for (let i = 0; i < 100; i++) {
  let session = driver.session();

  session
    .run('create (u:User {id: {id}}) return u', {id: _.random(100000)})
    .then(records => {
      console.log('=====================NUMBER'+i+'=======================');
      console.log(records)
      console.log('==============================================');
      session.close();
    })
    .catch(err => {
      console.error(err);
      session.close();
    });

}

The same problem appears using observer:

const _ = require('lodash'),
      neo4j = require('neo4j-driver').v1;

const driver = neo4j.driver('bolt://localhost:7687',
                            neo4j.auth.basic('neo4j',
                                             'neo4j'),
                            {connectionPoolSize: 1});

for (let i = 0; i < 100; i++) {
  let session = driver.session();

  session
    .run('create (u:User {id: {id}}) return u', {id: _.random(100000)})
    .subscribe({
      onNext(record) {

      },
      onCompleted(summary) {
        console.log('finished number ' + i);
        session.close();
      },
      onError(err) {
        console.error(err, 'itaration number' + i);
      }
    });
}

After removing session.close() this problem disappears in both cases.

When using lower number of session e.g. 5, then the same problem appears after few scripts run. However, all records are returned properly.
I wouldn't notice this if next test in my suite sometimes didn't strangely fail with timeout or even exception shown below when using match (u:Testing) detach delete u on afterEach hook.

2016-09-27 20:19:32.868+0000 ERROR [o.n.b.v.r.i.ErrorReporter] Client triggered an unexpected error [UnknownError]: Property[1075,used=false,prev=-1,next=-1] not in use. See debug.log for more details, reference 4c0fb1ed-ee5b-4036-a156-828a206cfc2e.
2016-09-27 20:19:32.868+0000 ERROR [o.n.b.v.r.i.ErrorReporter] Client triggered an unexpected error [UnknownError]: Property[1075,used=false,prev=-1,next=-1] not in use, reference 4c0fb1ed-ee5b-4036-a156-828a206cfc2e. Property[1075,used=false,prev=-1,next=-1] not in use
org.neo4j.kernel.impl.store.InvalidRecordException: Property[1075,used=false,prev=-1,next=-1] not in use
    at org.neo4j.kernel.impl.store.record.RecordLoad$1.verify(RecordLoad.java:55)
    at org.neo4j.kernel.impl.store.CommonAbstractStore.verifyAfterReading(CommonAbstractStore.java:1240)
    at org.neo4j.kernel.impl.store.CommonAbstractStore.readIntoRecord(CommonAbstractStore.java:1064)
    at org.neo4j.kernel.impl.store.CommonAbstractStore.getRecord(CommonAbstractStore.java:1042)
    at org.neo4j.kernel.impl.transaction.state.Loaders$2.load(Loaders.java:165)
    at org.neo4j.kernel.impl.transaction.state.Loaders$2.load(Loaders.java:145)
    at org.neo4j.kernel.impl.transaction.state.RecordChanges.getOrLoad(RecordChanges.java:72)
    at org.neo4j.kernel.impl.transaction.state.PropertyDeleter.deletePropertyChain(PropertyDeleter.java:45)
    at org.neo4j.kernel.impl.transaction.state.TransactionRecordState.getAndDeletePropertyChain(TransactionRecordState.java:336)
    at org.neo4j.kernel.impl.transaction.state.TransactionRecordState.nodeDelete(TransactionRecordState.java:322)
    at org.neo4j.kernel.impl.storageengine.impl.recordstorage.TransactionToRecordStateVisitor.visitDeletedNode(TransactionToRecordStateVisitor.java:89)
    at org.neo4j.storageengine.api.txstate.TxStateVisitor$Delegator.visitDeletedNode(TxStateVisitor.java:220)
    at org.neo4j.kernel.api.txstate.TransactionCountingStateVisitor.visitDeletedNode(TransactionCountingStateVisitor.java:100)
    at org.neo4j.kernel.impl.api.state.TxState$12.visitRemoved(TxState.java:339)
    at org.neo4j.kernel.impl.api.state.TxState$12.visitRemoved(TxState.java:335)
    at org.neo4j.kernel.impl.util.diffsets.SuperDiffSets.accept(SuperDiffSets.java:70)
    at org.neo4j.kernel.impl.util.diffsets.DiffSets.accept(DiffSets.java:41)
    at org.neo4j.kernel.impl.api.state.TxState.accept(TxState.java:274)
    at org.neo4j.kernel.impl.storageengine.impl.recordstorage.RecordStorageEngine.createCommands(RecordStorageEngine.java:304)
    at org.neo4j.kernel.impl.api.KernelTransactionImplementation.commit(KernelTransactionImplementation.java:431)
    at org.neo4j.kernel.impl.api.KernelTransactionImplementation.close(KernelTransactionImplementation.java:380)
    at org.neo4j.bolt.v1.runtime.internal.SessionStateMachine$State$3.commitTransaction(SessionStateMachine.java:187)
    at org.neo4j.bolt.v1.runtime.internal.SessionStateMachine$State$4.discardAll(SessionStateMachine.java:258)
    at org.neo4j.bolt.v1.runtime.internal.SessionStateMachine$State$4.pullAll(SessionStateMachine.java:237)
    at org.neo4j.bolt.v1.runtime.internal.SessionStateMachine.pullAll(SessionStateMachine.java:664)
    at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorkerFacade.lambda$pullAll$4(SessionWorkerFacade.java:74)
    at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorker.execute(SessionWorker.java:116)
    at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorker.executeBatch(SessionWorker.java:102)
    at org.neo4j.bolt.v1.runtime.internal.concurrent.SessionWorker.run(SessionWorker.java:82)
    at java.lang.Thread.run(Thread.java:745)

And error returned to client:

Structure {
  signature: 127,
  fields: 
   [ { code: 'Neo.DatabaseError.General.UnknownError',
       message: 'An unexpected failure occurred, see details in the database logs, reference number 4c0fb1ed-ee5b-4036-a156-828a206cfc2e.' } ] }

When I don't use tests that runs more sessions than connectionPoolSize and without afterEach hook, then everything is OK.

So to summarize:

  1. I hit NullPointerException in DB when running more sessions than connectionPoolSize
  2. After hitting NullPointerException, next test which is simple transaction will timeout.
  3. using afterEach hook that deletes all test nodes, sometimes I get UnknownError on client and InvalidRecordException in DB

I posted this on neo4j google groups and they redirected me here.

Too many "ECONNRESET" error

neo4j-javascript-driver - 1.0.1

I am using neo4j with enterprise-3.0.1 edition with your nodejs driver and getting too many (over 90%) ECONNRESET errors from the driver. As the same queries are working perfectly fine if used in neo4j browser client (which uses http protocol), I am expecting the problem is in the driver and hence besides mailing the issue to neo4j support I'm also adding the same here.

Awesome!

Hey, just wanted to thank you, guys.

It's definitely awesome that there is an official JS lib for neo4j, and double-awesoming is the fact that it's working over a binary protocol over websockets in a browser.

Mangled records returned from bolt driver.

local neo4j version: 3.0.0-M05
driver version 1.0.0

code:

'use strict';
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "-----"));

var session = driver.session();

session.run("MATCH (n:ATTRACTION) RETURN n LIMIT 20;")
    .subscribe(
        {
            onNext: function (record) {
                var node = record.get('n');
                console.log(node);
            },
            onCompleted: function () {
                // Completed!
                session.close();
            },
            onError: function (error) {
                console.log(error);
            }
        }
    );

all the nodes look fine, but one looks like this:

Node {
  identity: Integer { low: 4373, high: 0 },
  labels: 
   [ '�q��N�\u0011\u0015��',
     Integer { low: 65, high: 0 },
     Integer { low: 84, high: 0 },
     Integer { low: 84, high: 0 } ],
  properties: Integer { low: 82, high: 0 } }

it's a fairly random smattering. any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.