Description
An exception thrown inside a transaction which has a code
property, but that property doesn't conform to the format used by Neo4j's internal errors, will result in a TypeError.
Neo4j Version: 3.5.5 Community (I doubt the server version matters much)
Neo4j Mode: Single instance
Driver version: JS driver 1.7.6
Operating System: Heroku 18
Steps to reproduce
Throw an exception that includes a code
property inside a transaction, as in this reproducer:
const neo4j = require('neo4j-driver').v1;
const graphenedbURL = process.env.GRAPHENEDB_BOLT_URL;
const graphenedbUser = process.env.GRAPHENEDB_BOLT_USER;
const graphenedbPass = process.env.GRAPHENEDB_BOLT_PASSWORD;
const driver = neo4j.driver(graphenedbURL, neo4j.auth.basic(graphenedbUser, graphenedbPass), {});
driver.onError = console.error;
const p = driver.session().readTransaction(async tx => {
const result = await tx.run("MATCH (o) RETURN o", {});
const err = new Error("foo");
err.code = 404;
throw err;
});
p.catch(console.error);
p.finally(() => {
driver.close();
});
Expected behavior
The foo
exception propagates to the p
promise and is caught.
Actual behavior
A TypeError is thrown inside the Neo4j driver.
TypeError: code.indexOf is not a function
at Function._isTransientError (/home/rmeador/Projects/neo4j-bug-repro/node_modules/neo4j-driver/lib/v1/internal/transaction-executor.js:217:16)
at Function._canRetryOn (/home/rmeador/Projects/neo4j-bug-repro/node_modules/neo4j-driver/lib/v1/internal/transaction-executor.js:206:129)
at TransactionExecutor._retryTransactionPromise (/home/rmeador/Projects/neo4j-bug-repro/node_modules/neo4j-driver/lib/v1/internal/transaction-executor.js:85:72)
at /home/rmeador/Projects/neo4j-bug-repro/node_modules/neo4j-driver/lib/v1/internal/transaction-executor.js:65:22
at process._tickCallback (internal/process/next_tick.js:68:7)
This appears to be due to the driver trying to interrogate the code
property of the Error, which for internally-generated errors is a String, but in my usage is a Number. I don't believe the driver should have an opinion on how I structure the Errors in my application.
I encountered this error on driver version 1.7.6, but the code appears to be unchanged on 4.0, so I assume it is present there as well.
I intend to submit a PR to fix this by checking that the error is a Neo4jError
, since it seems to me that the driver should only be trying to understand errors that it has created. If that's not the right approach, let me know.