cancel
Showing results for 
Search instead for 
Did you mean: 

Error not returning to the Golang driver

renatospaka
Graph Voyager

Hello folks.

I have this method to delete a Person from my Graph:

func (d FamilyRepositoryNeo4j) DeletePerson(id string) error {
    cypher := `
    MATCH (one:Person {uuid: $uuid})-[dBirth:BIRTH]->(:Day)
    DELETE one, dBirth
    `
    params := map[string]interface{}{
        "uuid": id,
    }
    result, err := d.Session.Session.Run(cypher, params)
    if err != nil {
        return err
    }

    if result.Err() != nil  {
        log.Printf("DeletePerson: result.Err() %v", result.Err())
        return result.Err()
    } 
    return nil
}

Despite it is working fine for "happy path" situations, if there is another relationship with that Person (and there's a lot of relationships in this Graph), the Golang driver is not returning the error message. For its concerns, everything ran OK, no errors found.

However, Neo4j Browser returns the error:

Neo.ClientError.Schema.ConstraintValidationFailed
Cannot delete node<0>, because it still has relationships. To delete this node, you must first delete its relationships.

This is my current schema:

What I am doing wrong here or what did I miss?

  • Go
7 REPLIES 7

andreperez
Graph Buddy

The error message says you are trying to delete a node with a relationship still attached to it. Use DETACH DELETE instead, passing only the node to remove the node and the remaining relationships.

Neo4J won't delete the other relationships automatically, only the one you passed using the match query.

Hi Andre, thanks. But I know that...

The problem is that the Golang driver is not returning the error when deleting the Person.

So, for my app concerns, there is no error and everything ran OK. But if I query the same Person uuid again, I realize sh/he is still there.

This is the problem.

I need to figure out why those errors check I've coded are not working. BTW, I copied them from this sample in Github

Hi,

What version of the Go driver are you using (and version of Neo4j)?
Also, the code here does not close the session. When is the session created and when is it closed?

I slightly changed the code:

func (d *FamilyRepositoryNeo4j) DeletePerson(id string) error {
	cypher := `
    MATCH (one:Person {uuid: $uuid})-[dBirth:BIRTH]->(:Day)
    DELETE one, dBirth
    `
	session := d.Driver.NewSession(neo4j.SessionConfig{})
	defer session.Close()

	result, err := session.Run(cypher, map[string]interface{}{
		"uuid": id,
	})
	if err != nil {
		return err
	}

	if result.Err() != nil {
		log.Printf("DeletePerson: result.Err() %v", result.Err())
		return result.Err()
	}
	return nil
}

Although the deletion rightfully does not happen when the node has other relationships, I can confirm there is no error raised by the Go driver (latest version). I'll investigate, thanks for the report.

The way things are currently implemented, the only option is to call result.Next(), either directly or via result.Consume()... which is a bit un-intuitive when running queries without RETURN clause:

func (d *FamilyRepositoryNeo4j) DeletePerson(id string) error {
	cypher := `
    MATCH (one:Person {uuid: $uuid})-[dBirth:BIRTH]->(:Day)
    DELETE one, dBirth
    `
	session := d.Driver.NewSession(neo4j.SessionConfig{
		BoltLogger: neo4j.ConsoleBoltLogger(),
	})
	defer session.Close()

	result, err := session.Run(cypher, map[string]interface{}{
		"uuid": id,
	})
	if err != nil {
		return err
	}

	if _, err = result.Consume(); err != nil {
		log.Printf("DeletePerson failed with: %v", err)
		return err
	}
	return nil
}

Hello Florent.

These are the packages I am using nowadays:

module github.com/heykidhealth/emr

go 1.16

require (
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/gofiber/fiber/v2 v2.17.0
	github.com/gofiber/jwt/v2 v2.2.6
	github.com/golang-jwt/jwt v3.2.2+incompatible
	github.com/joho/godotenv v1.3.0
	github.com/neo4j/neo4j-go-driver/v4 v4.2.4
	github.com/satori/go.uuid v1.2.0
	github.com/stretchr/testify v1.7.0
	golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
)

Regarding the error, the situation remains the same.

This is my current delete method:

func (d FamilyRepositoryNeo4j) DeletePerson(id string) error {
	cypher := `
	MATCH (one:Person {uuid: $uuid})-[dBirth:BIRTH]->(:Day)
	DELETE one, dBirth
	`
	params := map[string]interface{}{
		"uuid": id,
	}
	result, err := d.Session.Session.Run(cypher, params)
	if err != nil {
		log.Printf("DeletePerson: err %v", err)
		return err
	}

	// if result.Err() != nil  {
	// 	log.Printf("DeletePerson: result.Err() %v", result.Err())
	// 	return result.Err()
	// } 

	if _, err = result.Consume(); err != nil {
		log.Printf("DeletePerson failed with: %v", err)
		return err
	}

	log.Printf("DeletePerson: %v", "no errors")
	return nil
}

This is the execution log for id = "31ae9e63-7217-47aa-9330-ab4d588af00e":

2021/08/23 20:01:41 EMR: initializing
2021/08/23 20:01:41 neo4j: initializing
2021/08/23 20:01:41 neo4j: connection in process
2021/08/23 20:01:41 neo4j: driver connected to the server
2021/08/23 20:01:41 neo4j: session established in write mode
2021/08/23 20:01:41 neo4j: session is valid
2021/08/23 20:01:41 http: initializing (on Fiber)
2021/08/23 20:01:41 family: initializing repository
2021/08/23 20:01:41 family: initializing service
2021/08/23 20:01:41 family: initializing controller
2021/08/23 20:01:41 routes: initializing family
2021/08/23 20:01:41 EMR: running on Fiber http listening port :8000
2021/08/23 20:01:54 DeletePerson: calling f.Repository.DeletePerson #31ae9e63-7217-47aa-9330-ab4d588af00e
2021/08/23 20:01:54 DeletePerson failed with: Neo4jError: Neo.ClientError.Schema.ConstraintValidationFailed (Cannot delete node<0>, because it still has relationships. To delete this node, you must first delete its relationships.)
2021/08/23 20:01:53 DELETE: [422] /person/31ae9e63-7217-47aa-9330-ab4d588af00e in 52.8094ms

And this is the HTTP call result:

HTTP/1.1 422 Unprocessable Entity
Date: Mon, 23 Aug 2021 23:01:54 GMT
Content-Type: application/json
Content-Length: 237
Vary: Origin
Access-Control-Allow-Origin: *
Connection: close

{
  "data": null,
  "message": "Neo4jError: Neo.ClientError.Schema.ConstraintValidationFailed (Cannot delete node\u003c0\u003e, because it still has relationships. To delete this node, you must first delete its relationships.)",
  "status": "error"
}

Despite it is working, it is a very unusual, confusing, and completely non-intuitive solution.
The best would be the Session.Run returns with an error.

Anyway, it works...

For the time being, that's unfortunately the best you can do.
We're discussing within the team to tackle this kind of scenario better for all official drivers.