# How to detech which Cypher statement goes wrong

**URL:** <https://community.neo4j.com/t/how-to-detech-which-cypher-statement-goes-wrong/7312>\
**Category:** Cypher\
**Created:** [May 12, 2019, 11:21am UTC](https://community.neo4j.com/t/how-to-detech-which-cypher-statement-goes-wrong/7312 "2019-05-12T11:21:32Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![johnhckuo](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/johnhckuo/32/4762_2.png) [@johnhckuo](https://community.neo4j.com/u/johnhckuo)\
**Post date:** [May 12, 2019, 11:21am UTC](https://community.neo4j.com/t/how-to-detech-which-cypher-statement-goes-wrong/7312/1 "2019-05-12T11:21:32Z")

</div>

Greetings,

Recently I'm looking into the docs of Cypher and write a simple Cypher query in Golang,  
I've tried to use multiple statements inside a single transaction.

but If I input a invalid id of children or parent and make the middle `MATCH` statements failed on purpose, the transaction will not return anything for me (`result.Next() is nil`). So the whole function will only return `No data returned`

in this way I cannot know which statement goes wrong. Any suggestions?

Thanks a lot!

```auto
_, err = session.WriteTransaction(func(transaction neo4j.Transaction) (interface{}, error) {
		result, err := transaction.Run(
			`CREATE (currentNode:Location $props)
			WITH currentNode
			OPTIONAL MATCH (children:Location) WHERE children.id IN $children
			MERGE (currentNode)-[:contains]->(children)
			WITH currentNode, children
			OPTIONAL MATCH (parent:Location{id:currentNode.parent})
			MERGE (parent) -[:contains]-> (currentNode)
			WITH currentNode, parent, children
			OPTIONAL MATCH path=(currentNode)-[contains*]-> (currentNode)
			WHERE length(path) > 0
			RETURN {cycle: length(path), children: children.id, parent: parent.id}`, map[string]interface{}{"props": input, "children": child})
		if err != nil {
			return nil, err
		}

		if result.Next() {

			returnedMap := result.Record().GetByIndex(0).(map[string]interface{})
			cycle := returnedMap["cycle"].(int64)
			parent := returnedMap["parent"].(string)
			children := returnedMap["parent"].(string)
			if parent == "" {
				errMsg := "Cannot find the given parent of the location"
				return nil, errors.New(errMsg)
			} else if children == "" {
				errMsg := "Cannot find the given children of the location"
				return nil, errors.New(errMsg)
			} else if cycle > 0 {
				errMsg := " Cycle Detected"
				return nil, errors.New(errMsg)
			}

		} else {
			return nil, errors.New("No data returned")
		}

		if result.Err() != nil {
			return nil, result.Err()
		}
		return nil, nil

	})

```

---

<div class="post-metadata">

**Author:** ![kees.vegter](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/kees.vegter/32/668_2.png) [@kees.vegter](https://community.neo4j.com/u/kees.vegter)\
**Post date:** [May 13, 2019, 1:10pm UTC](https://community.neo4j.com/t/how-to-detech-which-cypher-statement-goes-wrong/7312/2 "2019-05-13T13:10:42Z")

</div>

HI John,

What you want to load?  
Assuming it is:  
(Location)-[:contains]-\>(Location)

First my comments on your statement:  
CREATE (currentNode:Location $props)  
WITH currentNode  
OPTIONAL MATCH (children:Location) WHERE children.id IN $children  
MERGE (currentNode)-[:contains]-\>(children)

The MERGE is never optional so if you want to merge an 'optional child' that will not work. Also you forgot the colon for the relationship type by the path= section

I think you should go the MERGE route all the way, make sure that you have an UNIQUE CONSTRAINT on Location.id

My cypher would be like this to create a structure:  
WITH $props as data  
MERGE (currentNode:Location { id: data.id })  
ON CREATE SET currentNode += data  
FOREACH (y in $children |  
MERGE (child:Location { id: y })  
MERGE (currentNode)-[:contains]-\>(child)  
)  
MERGE (parentNode:Location { id: data.parent} )  
MERGE (parentNode)-[:contains]-\>(currentNode)

Than in a second call i would check fo cyclic paths but you can add the also the MATCH line below the merge above:  
WITH $props as data  
MATCH path = (currentNode:Location { id: data.id})-[:contains0..\*]-\>(currentNode)  
WHERE length(path) \> 0  
RETURN currentNode{ cycle: length(path), children : [(currentNode)-[:contains]-\>(child:Location) | child.id ], parent: parentNode.id }

A note about the '0' in the variable path length query: When the path length = 0 you only have the currentNode back. This is faster than using OPTIONAL MATCH.

To give a final answer on how to detect if a cypher statement goes wrong, is to test it first in the neo4j browser and use explain/profile before your statement. You can use here :param to create query parameters.

I hope this will help you
