I am trying to develop custom User model/authentication code in Go on GAE. The following code is a simple modification of some code in the demos/guestbook application:
q := datastore.NewQuery("User").Filter("Email =", email)
users := make([]User, 0, 1)
if _, err := q.GetAll(c, &users); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
Where email is pulled from a form. It just queries the datastore for a User with the given email. It works fine if the User with the email exists, and dies with an "Internal Server Error" page if they don't. What I don't understand (I guess about error handling in Go, or maybe datastore querying), is why I can't do anything else within that if error block. A slight mod like this:
if _, err := q.GetAll(c, &users); err != nil {
fmt.Fprintf(w, "%s\n", "user not found")
}
produces the same "Internal Server Error" page instead of just printing "user not found".
Thanks!
It is tough to say without seeing the rest of your code, but the main point is that when you say:
if _, err := q.GetAll(c, &users); err != nil {
fmt.Fprintf(w, "%s\n", "user not found")
}
The inner statement will only be triggered if there was an error during the query, not if the query returns nothing. Therefore you aren't actually entering that block of code - my best guess (without seeing the code) is that your Internal Server Error is being triggered elsewhere, perhaps somewhere where you are treating users as a variable that contains data. If you want to print out that message if no user was matched, you could do something simple like check the length of the response - if it is 0, no results were returned and you can print your message:
if len(users) == 0 {
fmt.Fprintf(w, "%s\n", "user not found")
}
There is likely a more idiomatic way, but I believe that will work for your situation (it will print just as you state there - you may want to handle it differently).
Related
db, err := sql.Open("sqlite3", "./map.gpkg")
if err != nil {
panic(err.Error())
}
defer db.Close()
_, err = db.Exec("SELECT load_extension('mod_spatialite');")
if err != nil {
panic(err.Error())
}
In the code above, SELECT load_extension('mod_spatialite'); When executing the line, the following error is returned:
panic: not authorized
I don't know why this error occurs, it seems that the extension is not loaded properly
Also, what files do I need to download to use the mod_spatialite extension? Or is it possible to simply use the extension by loading it?
please help
I'm trying to PUT my GridDB container (a simple container for users on my website) but it's having issues.
I've confirmed that the sample code for the go_client works so it's not an issue of improper build or anything of that sort.
func getAdminUsers(c echo.Context) error {
var tmp []interface{}
col, err1 := gridstore.GetContainer("users")
if err1 != nil {
fmt.Println("get container failed")
}
col.SetAutoCommit(true)
// Create normal query
query, err := col.Query("SELECT *")
if err != nil {
fmt.Println("create query failed")
}
//Execute query
rs, err := query.Fetch(true)
if err != nil {
fmt.Println("create rs from query failed")
}
for rs.HasNext() {
// Update row
rrow, err := rs.NextRow()
if err != nil {
fmt.Println("NextRow from rs failed")
}
tmp = rrow
fmt.Println("Person: name=", rrow[0], " status=", rrow[1], " count=", rrow[2], " lob=", rrow[3])
}
col.Commit()
fmt.Println(tmp)
return c.Render(http.StatusOK, "admin", "admin")
}
My container is properly being written but for some reason the querying isn't working. This is rather basic code so I expect there's some minor detail I'm missing somewhere.
As of now, I'm getting errors here: "get container failed". My error could either be from writing or querying, though I suspect it's from querying.
Can you try initializing your container by using the CreateContainerInfo instead? It will create container if it doesn't exist, but if it does exist, it's a more robust method of calling your container.
conInfo, _ := griddb_go.CreateContainerInfo("Users",
[][]interface{}{
{"email", griddb_go.TYPE_STRING},
{"password", griddb_go.TYPE_BLOB}},
griddb_go.CONTAINER_COLLECTION,
true)
col, _ := gridstore.PutContainer(conInfo, false)
According to the documentation, it should be possible to retrieve an ancestor and all of its descendants, regardless of their kind.
In my implementation, I have a different kind of ancestor and descendant. The following codes however always returns the error "invalid entity type":
q := datastore.NewQuery("").Ancestor(tomKey)
t := q.Run(ctx)
for {
var x interface{}
_, err := t.Next(&x)
if err == datastore.Done {
break
}
if err != nil {
log.Errorf(ctx, "Error fetching entity: %v", err)
break
}
}
It seems that the call to t.Next(&x) expects a specific type instead of an empty interface. Would somebody please help me to resolve this problem?
I don't know the documentation is wrong, but you can use datastore.PropertyList to fetch arbitrary value. like this:
var v datastore.PropertyList
key, err := iter.Next(&v)
...
props, err := v.Save()
...
See this docs for more information.
I am learning how to create Golang tests for an Appengine app.
The documentation examples don't make sense to me.
https://cloud.google.com/appengine/docs/standard/go/tools/localunittesting/reference
Documentation seems to say you can create a context := aetest.NewContext()
When I attempt to do so, I'm getting an error that aetest.NewContext requires arguments.
$ go test -v
./skincare_test.go:12: not enough arguments in call to aetest.NewContext
have ()
want (*aetest.Options)
./skincare_test.go:12: assignment count mismatch: 3 = 2
FAIL _/Users/Bryan/work/gocode/skincarereview [build failed]
content of skincare_test.go:
package skincare
import (
"net/http"
"net/http/httptest"
"testing"
"appengine/aetest"
)
func TestIndexHandler(t *testing.T) {
ctx, done, err := aetest.NewContext()
if err != nil {
t.Fatal(err)
}
defer done()
req, err := http.NewRequest("GET", "/", nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler := http.HandlerFunc(root)
handler.ServeHTTP(rr, req)
if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
expected := "<div>Name"
if rr.Body.String() != expected {
t.Errorf("handler returned expected body: got %v want %v",
rr.Body.String(), expected)
}
}
I learn best by looking at example code, where can I find examples of Tests for Go web applications that use Appengine datastore?
The examples in the documentation are so simple that I don't see how I'm supposed to do more complicated testing.
It says 2 things:
1) You are missing a required parameter *aetest.Options
2) that you can NOT assign result aetest.NewContext() that consist of 2 variable to a set of 3 variables.
Check what is the output of the function. I guess it is just (context.Context, error) - I suspect the done is moved to the *aetest.Options somehow.
Unfortunately my access to docs is blocked right now.
You are using the old version of the app engine package (appengine/aetest instead of google.golang.org/appengine/aetest). The newer version does not require arguments.
I am recently getting an error that I have never seen before when making a simple datastore.GetAll() request. I can't figure out what it means and I can't find any documentation with the error message or any help from Googleing the error message.
Here's my code:
type MyUnderlyingStruct struct {
ApplyTo *datastore.Key
ApplyFrom *datastore.Key
Amount float64
LocationKey *datastore.Key
DepartmentKey *datastore.Key
SubjectAreaKey *datastore.Key
}
type MyStruct []MyUnderlyingStruct
//In the case where I get the error someKey is a valid, complete Key value
// of a different kind that what we are querying for and there is actually
// an entity in my datastore that matches this query
func (x *MyStruct) Load(w http.ResponseWriter, r *http.Request, someKey *datastore.Key) (error) {
c := appengine.NewContext(r)
q := datastore.NewQuery("MyUnderlyingStruct_KindName").Order("-Amount")
if someKey != nil { q = q.Filter("ApplyTo=", someKey) }
keys, err := q.GetAll(c,x)
if _, ok := err.(*datastore.ErrFieldMismatch); ok { err = nil }
if err != nil && err != datastore.Done {return err}
return nil
}
Which returns this error:
API error 1 (datastore_v3: BAD_REQUEST): The kind is the empty string.
Can anyone tell me why I am getting this error, or what it is trying to tell me?
Looking at your issue on the first glance (because I am not familiar with Google's datastore API), it seems to me the problem is a result of zeroed-memory initialization using new keyword.
When a struct is created with the keyword without assigning starting values for the fields, 0's are given as default. When mapped to string, it's "" (empty). Go actually threw a very helpful error for you.
As you have pointed out, you have used Mykey := new(datastore.Key). Thanks for your generosity and this can serve as answer for future users.