I’ve been developing with Couchbase and the Go SDK for a while now, but recently I ran into an issue that I deemed to be a bug in the SDK after hours of troubleshooting. I was trying to execute a N1QL query that I knew for a fact had results. The problem was that I was not seeing any of those results within the Go application.
After hashing things out with the Go SDK engineer, it was not a bug, but in fact some user errors. How embarrassing right?
We’re going to see what I was doing wrong and the steps that were used to correct the problem.
In my Go application I had several data structures which were to be modeled after the data that I was storing in Couchbase. One of those data structures looked like the following:
1 2 3 4 5 6 7 |
type Blog struct { Type string `json:"type,omitempty"` Pid string `json:"pid,omitempty"` Title string `json:"title,omitempty"` Content string `json:"content,omitempty"` Timestamp int `json:"timestamp,omitempty"` } |
Above is a very simple data structure that represents a very simple document model.
To query all Blog
documents in my Couchbase Bucket, I was executing the following code:
1 2 3 4 5 6 7 8 9 10 11 12 |
query := gocb.NewN1qlQuery("SELECT `" + bucket.Name() + "`.* FROM `" + bucket.Name() + "` WHERE type = 'blog'") rows, err := bucket.ExecuteN1qlQuery(query, nil) if err != nil { fmt.Println(err.Error()) return } var row Blog for rows.Next(&row) { fmt.Println(row) row = Blog{} } rows.Close() |
When running my application, no results were printing even though I could validate elsewhere that my query was correct. The .Next
function was always returning false.
The next logical step was to make sure that Couchbase was receiving the request correctly from the Go SDK powered application. This was verified through monitoring the Couchbase logs. The logs had indicated that everything added up.
I then changed my code a bit:
1 2 3 4 5 6 7 8 9 |
query := gocb.NewN1qlQuery("SELECT `" + bucket.Name() + "`.* FROM `" + bucket.Name() + "` WHERE type = 'blog'") rows, err := bucket.ExecuteN1qlQuery(query, nil) if err != nil { fmt.Println(err.Error()) return } var row Blog rows.One(&row) fmt.Println(row) |
Instead of using the .Next
function, I used the .One
function. One of the results was printing, however, I didn’t realize it was a partial print.
After speaking with Brett Lawson, the Go SDK engineer, he concluded that I was receiving errors that were causing the results to fail.
But wait a second. Doesn’t the following print out my errors?:
1 2 3 4 |
if err != nil { fmt.Println(err.Error()) return } |
The above code would print out errors with the execution of the query. I was actually having errors elsewhere, after the query had executed and I had received results.
Brett recommended that I change my code to the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
query := gocb.NewN1qlQuery("SELECT `" + bucket.Name() + "`.* FROM `" + bucket.Name() + "` WHERE type = 'blog'") rows, err := bucket.ExecuteN1qlQuery(query, nil) if err != nil { fmt.Println(err.Error()) return } var row Blog for rows.Next(&row) { fmt.Println(row) row = Blog{} } err = rows.Close() fmt.Println(err) |
Notice that I’m printing out the error on the .Close
function this time.
It turns out that there were errors. The problem was that my results were not mapping correctly to my data structure. More specifically, I was having a problem with the Timestamp
property.
I was saving the Timestamp
as int64
data, but I was trying to read it as if it were int
. This minor detail was causing an error that I wasn’t catching, leading me to believe that my results were empty and that there was a bug in the Go SDK.
Conclusion
The moral of the story here is that if a Go function returns an error, definitely take advantage of the information and do something with it. Don’t omit the error from your code and proceed like it might not exist. It could cost you hours of frustration down the road.
To see my embarrassing issue ticket and the proper resolution, check out the Jira tracker here.
For more information on using the Go SDK with Couchbase, check out the Couchbase Developer Portal.