Skip to content

Instantly share code, notes, and snippets.

@jonleopard
Last active January 26, 2023 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonleopard/83cbddf300b55e2e0abb9346fb60fd3c to your computer and use it in GitHub Desktop.
Save jonleopard/83cbddf300b55e2e0abb9346fb60fd3c to your computer and use it in GitHub Desktop.
TRC runtime error: invalid memory address or nil pointer dereference
goroutine 5 [running]:
runtime/debug.Stack()
/usr/local/Cellar/go/1.19.5/libexec/src/runtime/debug/stack.go:24 +0x65
main.(*application).serverError(0xc000280720, {0x1523030, 0xc0000b42a0}, {0x15203a0?, 0xc00040f3e0?})
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/helpers.go:48 +0x66
main.(*application).recoverPanic.func1.1()
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/middleware.go:51 +0x157
panic({0x140b340, 0x178e830})
/usr/local/Cellar/go/1.19.5/libexec/src/runtime/panic.go:884 +0x212
github.com/jonleopard/mailmon/internal/database.(*Queries).GetUser(0x0, {0x1523570, 0xc000120000}, {0xc0000af380, 0xc})
/Users/jon/projects/golang-learning/letsgo/mailmon/internal/database/query.sql.go:151 +0x95
github.com/jonleopard/mailmon/internal/models.Authenticate({0xc0000af380?, 0xc0000aaa00?}, {0xc00041034e, 0x8})
/Users/jon/projects/golang-learning/letsgo/mailmon/internal/models/users.go:34 +0x4e
main.(*application).handleUserLoginPost(0xc000280720, {0x1522d30, 0xc00009e0f0}, 0xc0000aaa00)
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/handlers.go:221 +0x31a
net/http.HandlerFunc.ServeHTTP(0xc000135540?, {0x1522d30?, 0xc00009e0f0?}, 0x0?)
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f
github.com/alexedwards/scs/v2.(*SessionManager).LoadAndSave.func1({0x1523030, 0xc0000b42a0}, 0xc0000aa900)
/Users/jon/go/pkg/mod/github.com/alexedwards/scs/v2@v2.5.0/session.go:148 +0x216
net/http.HandlerFunc.ServeHTTP(0xc0002808a0?, {0x1523030?, 0xc0000b42a0?}, 0xc0000c2170?)
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f
github.com/go-chi/chi/v5.(*ChainHandler).ServeHTTP(0x1408a80?, {0x1523030?, 0xc0000b42a0?}, 0xc0004067c5?)
/Users/jon/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.7/chain.go:31 +0x2c
github.com/go-chi/chi/v5.(*Mux).routeHTTP(0xc00007e4e0, {0x1523030, 0xc0000b42a0}, 0xc0000aa900)
/Users/jon/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.7/mux.go:442 +0x216
net/http.HandlerFunc.ServeHTTP(0xc000000140?, {0x1523030?, 0xc0000b42a0?}, 0xc0000aa900?)
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f
github.com/go-chi/cors.(*Cors).Handler.func1({0x1523030, 0xc0000b42a0}, 0xc0000aa900)
/Users/jon/go/pkg/mod/github.com/go-chi/cors@v1.2.1/cors.go:228 +0x1bd
net/http.HandlerFunc.ServeHTTP(0x1523538?, {0x1523030?, 0xc0000b42a0?}, 0x178e5d0?)
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f
github.com/go-chi/chi/v5.(*Mux).ServeHTTP(0xc00007e4e0, {0x1523030, 0xc0000b42a0}, 0xc0000aa800)
/Users/jon/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.7/mux.go:88 +0x310
main.secureHeaders.func1({0x1523030, 0xc0000b42a0}, 0x4?)
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/middleware.go:20 +0x3af
net/http.HandlerFunc.ServeHTTP(0xc00009c120?, {0x1523030?, 0xc0000b42a0?}, 0xc00014b9c8?)
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f
main.(*application).logRequest.func1({0x1523030, 0xc0000b42a0}, 0xc0000aa800)
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/middleware.go:35 +0x19b
net/http.HandlerFunc.ServeHTTP(0x0?, {0x1523030?, 0xc0000b42a0?}, 0xffffffffffffffff?)
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f
main.(*application).recoverPanic.func1({0x1523030?, 0xc0000b42a0?}, 0xc00014bae0?)
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/middleware.go:55 +0x93
net/http.HandlerFunc.ServeHTTP(0x0?, {0x1523030?, 0xc0000b42a0?}, 0x12be934?)
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f
net/http.serverHandler.ServeHTTP({0x1522160?}, {0x1523030, 0xc0000b42a0}, 0xc0000aa800)
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2947 +0x30c
net/http.(*conn).serve(0xc000000a00, {0x15235e0, 0xc000280b10})
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:1991 +0x607
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:3102 +0x4db
func (app *application) handleUserSignupPost(w http.ResponseWriter, r *http.Request) {
// Declare an zero-valued instance of our userSignupForm struct.
var form models.UserSignupForm
// Parse the form data into the userSignupForm struct.
err := app.decodePostForm(r, &form)
if err != nil {
app.clientError(w, http.StatusBadRequest)
return
}
// Validate the form contents using our helper functions.
form.CheckField(validator.NotBlank(form.Name), "name", "This field cannot be blank")
form.CheckField(validator.NotBlank(form.Email), "email", "This field cannot be blank")
form.CheckField(validator.Matches(form.Email, validator.EmailRX), "email", "This field must be a valid email address")
form.CheckField(validator.NotBlank(form.Password), "password", "This field cannot be blank")
form.CheckField(validator.MinChars(form.Password, 8), "password", "This field must be at least 8 characters long")
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(form.Password), 12)
// If there are any errors, redisplay the signup form along with a 422
// status code.
if !form.Valid() {
data := app.newTemplateData(r)
data.Form = form
app.render(w, http.StatusUnprocessableEntity, "signup.html", data)
return
}
// Try to create a new user record in the database. If the email already
// exists then add an error message to the form and re-display it.
// Do I need to return anything from the database? I am using _, err
err = app.repo.CreateUser(context.Background(), database.CreateUserParams{
Name: form.Name,
Email: form.Email,
HashedPassword: string(hashedPassword),
})
// TODO: Check if this is a sane way of checking for the 23505 error code.
if err != nil {
var pqErr *pq.Error
if errors.As(err, &pqErr) && pqErr.Code == "23505" {
form.AddFieldError("email", "Email address is already in use")
data := app.newTemplateData(r)
data.Form = form
app.render(w, http.StatusUnprocessableEntity, "signup.html", data)
} else {
app.serverError(w, err)
}
return
}
// Otherwise add a confirmation flash message to the session confirming that
// their signup worked.
app.sessionManager.Put(r.Context(), "flash", "Your signup was successful. Please log in.")
// And redirect the user to the login page.
http.Redirect(w, r, "/user/login", http.StatusSeeOther)
}
func (q *Queries) GetUser(ctx context.Context, email string) (*GetUserRow, error) {
row := q.db.QueryRowContext(ctx, getUser, email)
var i GetUserRow
err := row.Scan(&i.ID, &i.HashedPassword)
return &i, err
}
func Authenticate(email, password string) (int, error) {
// Retrieve the id and hashed password associated with the given email. If
// no matching email exists we return the ErrInvalidCredentials error.
var id int
var hashedPassword []byte
repo := database.Repo{}
_, err := repo.GetUser(context.Background(), email)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return 0, ErrInvalidCredentials
} else {
return 0, err
}
}
// Check whether the hashed password and plain-text password provided match.
// If they don't, we return the ErrInvalidCredentials error.
err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(password))
if err != nil {
if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) {
return 0, ErrInvalidCredentials
} else {
return 0, err
}
}
// Otherwise, the password is correct. Return the user ID.
return id, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment