Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Commit

Permalink
add custom errors from central repo
Browse files Browse the repository at this point in the history
  • Loading branch information
Frecherenkel60 committed May 13, 2024
1 parent 3280157 commit 07fb361
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 209 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0
github.com/truemail-rb/truemail-go v1.1.3
github.com/wwi21seb-projekt/errors-go v0.1.0
golang.org/x/crypto v0.23.0
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ github.com/vanng822/go-premailer v0.0.0-20191214114701-be27abe028fe/go.mod h1:JT
github.com/vanng822/go-premailer v1.21.0 h1:qIwX4urphNPO3xa60MGqowmyjzzMtFacJPKNrt1UWFU=
github.com/vanng822/go-premailer v1.21.0/go.mod h1:6Y3H2NzNmK3sFBNgR1ENdfV9hzG8hMzrA1nL/XBbbP4=
github.com/vanng822/r2router v0.0.0-20150523112421-1023140a4f30/go.mod h1:1BVq8p2jVr55Ost2PkZWDrG86PiJ/0lxqcXoAcGxvWU=
github.com/wwi21seb-projekt/errors-go v0.1.0 h1:JluJstVclUW39zkOa4WiJ5UV2NeqIStae31tm0EQTpA=
github.com/wwi21seb-projekt/errors-go v0.1.0/go.mod h1:PWCPplYjGwrfrp+arG5WmfFA0ElenW/yRwV72iBawcM=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
Expand Down
57 changes: 30 additions & 27 deletions internal/handlers/post_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ package handlers
import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
"github.com/wwi21seb-projekt/server-alpha/internal/managers"
"github.com/wwi21seb-projekt/server-alpha/internal/schemas"
"github.com/wwi21seb-projekt/server-alpha/internal/utils"
"net/http"
"regexp"
"strconv"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/wwi21seb-projekt/errors-go/goerrors"
"github.com/wwi21seb-projekt/server-alpha/internal/managers"
"github.com/wwi21seb-projekt/server-alpha/internal/schemas"
"github.com/wwi21seb-projekt/server-alpha/internal/utils"

"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"

Expand All @@ -37,6 +39,7 @@ type PostHandler struct {

var hashtagRegex = regexp.MustCompile(`#\w+`)
var errTransaction = errors.New("error beginning transaction")
var bearerPrefix = "Bearer "

// NewPostHandler returns a new PostHandler with the provided managers and validator.
func NewPostHandler(databaseManager *managers.DatabaseMgr, jwtManager *managers.JWTMgr) PostHdl {
Expand All @@ -53,7 +56,7 @@ func (handler *PostHandler) CreatePost(ctx *gin.Context) {
// Begin a new transaction
tx := utils.BeginTransaction(ctx, handler.DatabaseManager.GetPool())
if tx == nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, errTransaction)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, errTransaction)
return
}
var err error
Expand Down Expand Up @@ -89,7 +92,7 @@ func (handler *PostHandler) CreatePost(ctx *gin.Context) {

_, err = tx.Exec(ctx, queryString, queryArgs...)
if err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand All @@ -103,13 +106,13 @@ func (handler *PostHandler) CreatePost(ctx *gin.Context) {
ON CONFLICT (content) DO UPDATE SET content=alpha_schema.hashtags.content
RETURNING hashtag_id`
if err := tx.QueryRow(ctx, queryString, hashtagId, hashtag).Scan(&hashtagId); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

queryString = "INSERT INTO alpha_schema.many_posts_has_many_hashtags (post_id_posts, hashtag_id_hashtags) VALUES($1, $2)"
if _, err = tx.Exec(ctx, queryString, postId, hashtagId); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}
}
Expand All @@ -120,7 +123,7 @@ func (handler *PostHandler) CreatePost(ctx *gin.Context) {

author := &schemas.AuthorDTO{}
if err := row.Scan(&author.Username, &author.Nickname); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand Down Expand Up @@ -155,7 +158,7 @@ func (handler *PostHandler) DeletePost(ctx *gin.Context) {
// Begin a new transaction
tx := utils.BeginTransaction(ctx, handler.DatabaseManager.GetPool())
if tx == nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, errTransaction)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, errTransaction)
return
}
var err error
Expand All @@ -174,25 +177,25 @@ func (handler *PostHandler) DeletePost(ctx *gin.Context) {
var content string
if err := row.Scan(&authorId, &content); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
utils.WriteAndLogError(ctx, schemas.PostNotFound, http.StatusNotFound, err)
utils.WriteAndLogError(ctx, goerrors.PostNotFound, http.StatusNotFound, err)
return
}

utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

userId := claims["sub"].(string)
if userId != authorId {
utils.WriteAndLogError(ctx, schemas.DeletePostForbidden, http.StatusForbidden,
utils.WriteAndLogError(ctx, goerrors.DeletePostForbidden, http.StatusForbidden,
errors.New("user is not the author of the post"))
return
}

// Delete the post
queryString = "DELETE FROM alpha_schema.posts WHERE post_id = $1"
if _, err = tx.Exec(ctx, queryString, postId); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand All @@ -206,7 +209,7 @@ func (handler *PostHandler) DeletePost(ctx *gin.Context) {

for _, hashtag := range hashtags {
if _, err = tx.Exec(ctx, queryString, hashtag); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}
}
Expand All @@ -225,7 +228,7 @@ func (handler *PostHandler) DeletePost(ctx *gin.Context) {
func (handler *PostHandler) QueryPosts(ctx *gin.Context) {
tx := utils.BeginTransaction(ctx, handler.DatabaseManager.GetPool())
if tx == nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, errTransaction)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, errTransaction)
return
}
var err error
Expand Down Expand Up @@ -274,7 +277,7 @@ func (handler *PostHandler) QueryPosts(ctx *gin.Context) {
paginatedResponse := createPaginatedResponse(posts, lastPostId, limit, count)

if err := utils.CommitTransaction(ctx, tx); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
}

utils.WriteAndLogResponse(ctx, paginatedResponse, http.StatusOK)
Expand All @@ -286,7 +289,7 @@ func (handler *PostHandler) HandleGetFeedRequest(ctx *gin.Context) {
// Begin a new transaction
tx := utils.BeginTransaction(ctx, handler.DatabaseManager.GetPool())
if tx == nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError,
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError,
errTransaction)
return
}
Expand All @@ -308,7 +311,7 @@ func (handler *PostHandler) HandleGetFeedRequest(ctx *gin.Context) {
paginatedResponse := createPaginatedResponse(posts, lastPostId, limit, records)

if err := utils.CommitTransaction(ctx, tx); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
}

utils.WriteAndLogResponse(ctx, paginatedResponse, http.StatusOK)
Expand Down Expand Up @@ -347,16 +350,16 @@ func determineFeedType(c *gin.Context, handler *PostHandler) (bool, jwt.Claims,
if authHeader == "" {
publicFeedWanted = true
} else {
if !strings.HasPrefix(authHeader, "Bearer ") || len(authHeader) <= len("Bearer ") {
if !strings.HasPrefix(authHeader, bearerPrefix) || len(authHeader) <= len(bearerPrefix) {
err = errors.New("invalid authorization header")
utils.WriteAndLogError(c, schemas.InvalidToken, http.StatusBadRequest, err)
utils.WriteAndLogError(c, goerrors.InvalidToken, http.StatusBadRequest, err)
return false, nil, err
}

jwtToken := authHeader[len("Bearer "):]
jwtToken := authHeader[len(bearerPrefix):]
claims, err = handler.JWTManager.ValidateJWT(jwtToken)
if err != nil {
utils.WriteAndLogError(c, schemas.Unauthorized, http.StatusUnauthorized, err)
utils.WriteAndLogError(c, goerrors.Unauthorized, http.StatusUnauthorized, err)
return false, nil, err
}

Expand Down Expand Up @@ -435,21 +438,21 @@ func retrieveFeed(ctx *gin.Context, tx pgx.Tx, publicFeedWanted bool,
// RetrieveCountAndRecords retrieves the count of posts that match the criteria and the corresponding post records.
// It executes the provided count and data queries, processes the results, and returns the post count along with the post DTOs.
func retrieveCountAndRecords(ctx *gin.Context, tx pgx.Tx, countQuery string, countQueryArgs []interface{},
dataQuery string, dataQueryArgs []interface{}) (int, []*schemas.PostDTO, *schemas.CustomError, int, error) {
dataQuery string, dataQueryArgs []interface{}) (int, []*schemas.PostDTO, *goerrors.CustomError, int, error) {
// Get the count of posts in the database that match the criteria
row := tx.QueryRow(ctx, countQuery, countQueryArgs...)

var count int
if err := row.Scan(&count); err != nil {
return 0, nil, schemas.DatabaseError, http.StatusInternalServerError, err
return 0, nil, goerrors.DatabaseError, http.StatusInternalServerError, err
}

var rows pgx.Rows
var err error

rows, err = tx.Query(ctx, dataQuery, dataQueryArgs...)
if err != nil {
return 0, nil, schemas.DatabaseError, http.StatusInternalServerError, err
return 0, nil, goerrors.DatabaseError, http.StatusInternalServerError, err
}

// Iterate over the rows and create the post DTOs
Expand All @@ -463,7 +466,7 @@ func retrieveCountAndRecords(ctx *gin.Context, tx pgx.Tx, countQuery string, cou

if err := rows.Scan(&post.PostId, &post.Author.Username, &post.Author.Nickname, &post.Author.ProfilePictureURL,
&post.Content, &createdAt, &longitude, &latitude, &accuracy); err != nil {
return 0, nil, schemas.DatabaseError, http.StatusInternalServerError, err
return 0, nil, goerrors.DatabaseError, http.StatusInternalServerError, err
}

if longitude.Valid && latitude.Valid {
Expand Down
40 changes: 21 additions & 19 deletions internal/handlers/subscription_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package handlers
import (
"errors"
"fmt"
"net/http"
"time"

"github.com/gin-gonic/gin"
"github.com/wwi21seb-projekt/errors-go/goerrors"
"github.com/wwi21seb-projekt/server-alpha/internal/managers"
"github.com/wwi21seb-projekt/server-alpha/internal/schemas"
"github.com/wwi21seb-projekt/server-alpha/internal/utils"
"net/http"
"time"

"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
Expand Down Expand Up @@ -45,7 +47,7 @@ func (handler *SubscriptionHandler) HandleGetSubscriptions(ctx *gin.Context) {
// Get pagination parameters
offset, limit, err := utils.ParsePaginationParams(ctx)
if err != nil {
utils.WriteAndLogError(ctx, schemas.BadRequest, http.StatusBadRequest, err)
utils.WriteAndLogError(ctx, goerrors.BadRequest, http.StatusBadRequest, err)
return
}

Expand All @@ -63,11 +65,11 @@ func (handler *SubscriptionHandler) HandleGetSubscriptions(ctx *gin.Context) {
findUserQuery := "SELECT user_id FROM alpha_schema.users WHERE username = $1"
rows, err := handler.DatabaseManager.GetPool().Query(ctx, findUserQuery, username)
if err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}
if !rows.Next() {
utils.WriteAndLogError(ctx, schemas.UserNotFound, http.StatusNotFound, errors.New("user not found"))
utils.WriteAndLogError(ctx, goerrors.UserNotFound, http.StatusNotFound, errors.New("user not found"))
return
}

Expand All @@ -91,7 +93,7 @@ func (handler *SubscriptionHandler) HandleGetSubscriptions(ctx *gin.Context) {

rows, err = handler.DatabaseManager.GetPool().Query(ctx, subscriptionQuery, jwtUserId, username)
if err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand All @@ -102,7 +104,7 @@ func (handler *SubscriptionHandler) HandleGetSubscriptions(ctx *gin.Context) {
followerId, followingId := uuid.UUID{}, uuid.UUID{}

if err := rows.Scan(&followingId, &followerId, &subscription.Username, &subscription.Nickname, &subscription.ProfilePictureUrl); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand All @@ -121,7 +123,7 @@ func (handler *SubscriptionHandler) HandleGetSubscriptions(ctx *gin.Context) {
row := handler.DatabaseManager.GetPool().QueryRow(ctx, countQuery, username)
var totalSubscriptions int
if err := row.Scan(&totalSubscriptions); err != nil {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand Down Expand Up @@ -150,11 +152,11 @@ func (handler *SubscriptionHandler) Subscribe(ctx *gin.Context) {
var subscribeeId string
if err = row.Scan(&subscribeeId); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
utils.WriteAndLogError(ctx, schemas.UserNotFound, http.StatusNotFound, err)
utils.WriteAndLogError(ctx, goerrors.UserNotFound, http.StatusNotFound, err)
return
}

utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand All @@ -165,7 +167,7 @@ func (handler *SubscriptionHandler) Subscribe(ctx *gin.Context) {

// Check and throw error if the user wants to subscribe to himself
if jwtUserId == subscribeeId {
utils.WriteAndLogError(ctx, schemas.SubscriptionSelfFollow, http.StatusNotAcceptable,
utils.WriteAndLogError(ctx, goerrors.SubscriptionSelfFollow, http.StatusNotAcceptable,
errors.New("user cannot subscribe to himself"))
return
}
Expand All @@ -177,14 +179,14 @@ func (handler *SubscriptionHandler) Subscribe(ctx *gin.Context) {

if err := rows.Scan(&subscriptionId); err != nil {
if !errors.Is(err, pgx.ErrNoRows) {
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}
}

if subscriptionId != uuid.Nil {
// User is already subscribed, since the subscriptionId is not nil
utils.WriteAndLogError(ctx, schemas.SubscriptionAlreadyExists, http.StatusConflict,
utils.WriteAndLogError(ctx, goerrors.SubscriptionAlreadyExists, http.StatusConflict,
errors.New("subscription already exists"))
return
}
Expand All @@ -195,7 +197,7 @@ func (handler *SubscriptionHandler) Subscribe(ctx *gin.Context) {
createdAt := time.Now()
if _, err := tx.Exec(ctx, queryString, subscriptionId, jwtUserId, subscribeeId, createdAt); err != nil {
log.Errorf("error while inserting subscription: %v", err)
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand Down Expand Up @@ -240,17 +242,17 @@ func (handler *SubscriptionHandler) Unsubscribe(ctx *gin.Context) {
var subscriberId, subscribeeId string
if err := row.Scan(&subscriberId, &subscribeeId); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
utils.WriteAndLogError(ctx, schemas.SubscriptionNotFound, http.StatusNotFound,
utils.WriteAndLogError(ctx, goerrors.SubscriptionNotFound, http.StatusNotFound,
errors.New("subscription not found"))
return
}
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

// Check and throw error if user wants to delete someone else's subscription
if subscriberId != jwtUserId {
utils.WriteAndLogError(ctx, schemas.UnsubscribeForbidden, http.StatusForbidden,
utils.WriteAndLogError(ctx, goerrors.UnsubscribeForbidden, http.StatusForbidden,
errors.New("you can only delete your own subscriptions"))
return
}
Expand All @@ -259,11 +261,11 @@ func (handler *SubscriptionHandler) Unsubscribe(ctx *gin.Context) {
queryString = "DELETE FROM alpha_schema.subscriptions WHERE subscription_id = $1"
if _, err := tx.Exec(ctx, queryString, subscriptionId); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
utils.WriteAndLogError(ctx, schemas.SubscriptionNotFound, http.StatusNotFound,
utils.WriteAndLogError(ctx, goerrors.SubscriptionNotFound, http.StatusNotFound,
errors.New("subscription not found"))
return
}
utils.WriteAndLogError(ctx, schemas.DatabaseError, http.StatusInternalServerError, err)
utils.WriteAndLogError(ctx, goerrors.DatabaseError, http.StatusInternalServerError, err)
return
}

Expand Down
Loading

0 comments on commit 07fb361

Please sign in to comment.