generated from tsivinsky/go-template
return Server.Error()
This commit is contained in:
45
main.go
45
main.go
@@ -30,13 +30,11 @@ func main() {
|
|||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||||
srv.Error(w, "empty body", err, 400)
|
return srv.Error("empty body", err, 400)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if body.Email == "" || body.Password == "" {
|
if body.Email == "" || body.Password == "" {
|
||||||
srv.Error(w, "email or password missing", nil, 400)
|
return srv.Error("email or password missing", nil, 400)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hash, err := bcrypt.GenerateFromPassword([]byte(body.Password), 10)
|
hash, err := bcrypt.GenerateFromPassword([]byte(body.Password), 10)
|
||||||
@@ -50,8 +48,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := user.Create(db); err != nil {
|
if err := user.Create(db); err != nil {
|
||||||
srv.Error(w, "failed to create user", err, 400)
|
return srv.Error("failed to create user", err, 400)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := user.FindByID(db); err != nil {
|
if err := user.FindByID(db); err != nil {
|
||||||
@@ -74,24 +71,20 @@ func main() {
|
|||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||||
srv.Error(w, "empty body", err, 400)
|
return srv.Error("empty body", err, 400)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if body.Email == "" || body.Password == "" {
|
if body.Email == "" || body.Password == "" {
|
||||||
srv.Error(w, "email or password missing", nil, 400)
|
return srv.Error("email or password missing", nil, 400)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user := &model.User{Email: body.Email}
|
user := &model.User{Email: body.Email}
|
||||||
if err := user.FindByEmail(db); err != nil {
|
if err := user.FindByEmail(db); err != nil {
|
||||||
srv.Error(w, "user not found", err, 404)
|
return srv.Error("user not found", err, 404)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(body.Password)); err != nil {
|
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(body.Password)); err != nil {
|
||||||
srv.Error(w, "invalid password", nil, 400)
|
return srv.Error("invalid password", nil, 400)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expiryTime := time.Now().Add(time.Hour * 24 * 30)
|
expiryTime := time.Now().Add(time.Hour * 24 * 30)
|
||||||
@@ -107,14 +100,12 @@ func main() {
|
|||||||
srv.Handle("POST /api/images", func(w http.ResponseWriter, r *http.Request) error {
|
srv.Handle("POST /api/images", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
userId, err := auth.GetUserIdFromRequest(r)
|
userId, err := auth.GetUserIdFromRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srv.Error(w, "unauthorized", err, 401)
|
return srv.Error("unauthorized", err, 401)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user := &model.User{Model: model.Model{ID: userId}}
|
user := &model.User{Model: model.Model{ID: userId}}
|
||||||
if err := user.FindByID(db); err != nil {
|
if err := user.FindByID(db); err != nil {
|
||||||
srv.Error(w, "user not found", nil, 401)
|
return srv.Error("user not found", nil, 401)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := io.ReadAll(r.Body)
|
data, err := io.ReadAll(r.Body)
|
||||||
@@ -128,8 +119,7 @@ func main() {
|
|||||||
ContentType: r.Header.Get("Content-Type"),
|
ContentType: r.Header.Get("Content-Type"),
|
||||||
}
|
}
|
||||||
if err := img.Create(db); err != nil {
|
if err := img.Create(db); err != nil {
|
||||||
srv.Error(w, "failed to save image to database: %v", err, 400)
|
return srv.Error("failed to save image to database: %v", err, 400)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return srv.JSON(w, img, 201)
|
return srv.JSON(w, img, 201)
|
||||||
@@ -138,14 +128,12 @@ func main() {
|
|||||||
srv.Handle("GET /api/images", func(w http.ResponseWriter, r *http.Request) error {
|
srv.Handle("GET /api/images", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
userId, err := auth.GetUserIdFromRequest(r)
|
userId, err := auth.GetUserIdFromRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srv.Error(w, "unauthorized", err, 401)
|
return srv.Error("unauthorized", err, 401)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := db.Queryx("SELECT * FROM images WHERE user_id = ?", userId)
|
rows, err := db.Queryx("SELECT * FROM images WHERE user_id = ?", userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srv.Error(w, "images not found", err, 400)
|
return srv.Error("images not found", err, 400)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
images := []model.Image{}
|
images := []model.Image{}
|
||||||
@@ -164,8 +152,7 @@ func main() {
|
|||||||
srv.Handle("GET /images/{id}", func(w http.ResponseWriter, r *http.Request) error {
|
srv.Handle("GET /images/{id}", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
img := &model.Image{ID: r.PathValue("id")}
|
img := &model.Image{ID: r.PathValue("id")}
|
||||||
if err := img.FindByID(db); err != nil {
|
if err := img.FindByID(db); err != nil {
|
||||||
srv.Error(w, "image not found", nil, 404)
|
return srv.Error("image not found", nil, 404)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", img.ContentType)
|
w.Header().Set("Content-Type", img.ContentType)
|
||||||
@@ -177,13 +164,11 @@ func main() {
|
|||||||
srv.Handle("DELETE /api/images/{id}", func(w http.ResponseWriter, r *http.Request) error {
|
srv.Handle("DELETE /api/images/{id}", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
img := &model.Image{ID: r.PathValue("id")}
|
img := &model.Image{ID: r.PathValue("id")}
|
||||||
if err := img.FindByID(db); err != nil {
|
if err := img.FindByID(db); err != nil {
|
||||||
srv.Error(w, "image not found", nil, 404)
|
return srv.Error("image not found", nil, 404)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := img.DeleteByID(db); err != nil {
|
if err := img.DeleteByID(db); err != nil {
|
||||||
srv.Error(w, "failed to delete image: %v", err, 500)
|
return srv.Error("failed to delete image: %v", err, 500)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return srv.JSON(w, struct {
|
return srv.JSON(w, struct {
|
||||||
|
|||||||
46
server.go
46
server.go
@@ -5,6 +5,16 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ApiError struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Err error `json:"error"`
|
||||||
|
Status int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *ApiError) Error() string {
|
||||||
|
return a.Message
|
||||||
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
addr string
|
addr string
|
||||||
mux *http.ServeMux
|
mux *http.ServeMux
|
||||||
@@ -19,8 +29,23 @@ func NewServer(addr string) *Server {
|
|||||||
|
|
||||||
func (s *Server) Handle(pattern string, handler func(w http.ResponseWriter, r *http.Request) error) {
|
func (s *Server) Handle(pattern string, handler func(w http.ResponseWriter, r *http.Request) error) {
|
||||||
s.mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
s.mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||||
if err := handler(w, r); err != nil {
|
err := handler(w, r)
|
||||||
s.Error(w, "something bad happened", err, 500)
|
if err != nil {
|
||||||
|
if e, ok := err.(*ApiError); ok {
|
||||||
|
var nestedErr *string
|
||||||
|
if e.Err != nil {
|
||||||
|
nestedErr = new(e.Err.Error())
|
||||||
|
}
|
||||||
|
s.JSON(w, map[string]any{
|
||||||
|
"message": e.Message,
|
||||||
|
"error": nestedErr,
|
||||||
|
}, e.Status)
|
||||||
|
} else {
|
||||||
|
s.JSON(w, map[string]any{
|
||||||
|
"message": "something bad happened",
|
||||||
|
"error": err.Error(),
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -31,19 +56,12 @@ func (s *Server) JSON(w http.ResponseWriter, data any, status int) error {
|
|||||||
return json.NewEncoder(w).Encode(data)
|
return json.NewEncoder(w).Encode(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Error(w http.ResponseWriter, msg string, err error, status int) {
|
func (s *Server) Error(msg string, err error, status int) error {
|
||||||
var e *string
|
return &ApiError{
|
||||||
if err != nil {
|
|
||||||
e = new(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
s.JSON(w, struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
Error *string `json:"error"`
|
|
||||||
}{
|
|
||||||
Message: msg,
|
Message: msg,
|
||||||
Error: e,
|
Err: err,
|
||||||
}, status)
|
Status: status,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ListenAndServe() error {
|
func (s *Server) ListenAndServe() error {
|
||||||
|
|||||||
Reference in New Issue
Block a user