Skip to content

TypeError when custom exception is thrown inside transaction handler #485

Closed
@ryanmeador

Description

@ryanmeador

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions