Skip to content

Commit 0491187

Browse files
committed
Added extensive logging to problem endpoint.
1 parent 6c454b8 commit 0491187

4 files changed

Lines changed: 213 additions & 20 deletions

File tree

controllers/problem_controller.go

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package controllers
22

33
import (
44
"context"
5-
"database/sql"
65
"encoding/json"
76
"fmt"
87
"net/http"
@@ -31,119 +30,183 @@ func NewProblemController(problemModule *modules.ProblemModule, logger zerolog.L
3130

3231
// CreateProblemHandler handles POST /api/v1/problems
3332
func (c *ProblemController) CreateProblemHandler(w http.ResponseWriter, r *http.Request) {
33+
c.Logger.Info().Msg("received request to create a new problem")
34+
3435
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
3536
defer cancel()
3637

3738
user, ok := ctx.Value(middleware.UserContextKey).(*middleware.User)
3839
if !ok {
40+
c.Logger.Error().Msg("user not found in context for problem creation")
3941
http.Error(w, "user not found in context", http.StatusUnauthorized)
4042
return
4143
}
44+
c.Logger.Info().Str("userID", user.ID).Msg("user authorized for problem creation")
4245

4346
var req models.CreateProblemRequest
4447
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
48+
c.Logger.Error().Err(err).Msg("invalid request body for problem creation")
4549
http.Error(w, "invalid request body", http.StatusBadRequest)
4650
return
4751
}
52+
c.Logger.Debug().
53+
Str("title", req.Title).
54+
RawJSON("description_json", req.DescriptionJSON).
55+
Msg("decoded create problem request body")
56+
4857
problemStatement, err := c.ProblemModule.CreateProblem(ctx, &req, user.ID)
4958
if err != nil {
50-
c.Logger.Error().Err(err).Msg("failed to create problem statement")
59+
c.Logger.Error().Err(err).
60+
Str("userID", user.ID).
61+
Str("title", req.Title).
62+
Msg("failed to create problem statement via module")
5163
http.Error(w, fmt.Sprintf("error creating problem statemnet: %v", err), http.StatusInternalServerError)
5264
return
5365
}
66+
67+
c.Logger.Info().Str("problemID", problemStatement.ID.String()).Msg("problem statement created successfully")
5468
pkg.WriteJSONResponseWithLogger(w, http.StatusCreated, problemStatement, &c.Logger)
5569
}
5670

5771
// ListProblemsHandler handles GET /api/v1/problems
5872
func (c *ProblemController) ListProblemsHandler(w http.ResponseWriter, r *http.Request) {
73+
c.Logger.Info().Msg("received request to list problems")
74+
5975
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
6076
defer cancel()
6177

6278
user, ok := ctx.Value(middleware.UserContextKey).(*middleware.User)
6379
if !ok {
80+
c.Logger.Error().Msg("user not found in context for listing problems")
6481
http.Error(w, "user not found in context", http.StatusUnauthorized)
6582
return
6683
}
84+
c.Logger.Info().Str("userID", user.ID).Msg("user authorized for listing problems")
6785

6886
problems, err := c.ProblemModule.GetProblemsByUserID(ctx, user.ID)
6987
if err != nil {
70-
c.Logger.Error().Err(err).Msg("failed to list problems by user id")
88+
c.Logger.Error().Err(err).Str("userID", user.ID).Msg("failed to list problems by user id via module")
7189
http.Error(w, "failed to retrieve problems", http.StatusInternalServerError)
7290
return
7391
}
7492

75-
// If no problems are found, it should return an empty list, not an error.
93+
c.Logger.Info().
94+
Str("userID", user.ID).
95+
Int("problem_count", len(problems)).
96+
Msg("successfully listed problems for user")
7697
pkg.WriteJSONResponseWithLogger(w, http.StatusOK, problems, &c.Logger)
7798
}
7899

79100
// GetProblemByIDHandler handles GET /api/v1/problems/{id}
80101
func (c *ProblemController) GetProblemByIDHandler(w http.ResponseWriter, r *http.Request) {
81102
problemID := r.PathValue("id")
103+
c.Logger.Info().Str("problemID", problemID).Msg("received request to get problem by ID")
104+
82105
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
83106
defer cancel()
84107

85108
problem, err := c.ProblemModule.GetProblemByID(ctx, problemID)
86109
if err != nil {
87-
c.Logger.Error().Err(err).Msg("failed to get problem by id")
88-
if err == sql.ErrNoRows {
110+
c.Logger.Error().Err(err).Str("problemID", problemID).Msg("failed to get problem by id via module")
111+
if err.Error() == "problem not found" { // Matching the error string from problem_module
89112
http.Error(w, "problem not found", http.StatusNotFound)
90-
} else {
91-
http.Error(w, "failed to retrive problem", http.StatusInternalServerError)
113+
return
92114
}
115+
http.Error(w, "failed to retrieve problem", http.StatusInternalServerError)
93116
return
94117
}
95118

119+
c.Logger.Info().Str("problemID", problemID).Msg("successfully retrieved problem by ID")
96120
pkg.WriteJSONResponseWithLogger(w, http.StatusOK, problem, &c.Logger)
97121
}
98122

99123
// UpdateProblemByIDHandler handles PUT /api/v1/problems/{id}
100124
func (c *ProblemController) UpdateProblemByIDHandler(w http.ResponseWriter, r *http.Request) {
101125
problemID := r.PathValue("id")
126+
c.Logger.Info().Str("problemID", problemID).Msg("received request to update problem by ID")
127+
102128
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
103129
defer cancel()
104130

105131
user, ok := ctx.Value(middleware.UserContextKey).(*middleware.User)
106132
if !ok {
133+
c.Logger.Error().Msg("user not found in context for updating problem")
107134
http.Error(w, "user not found in context", http.StatusUnauthorized)
108135
return
109136
}
137+
c.Logger.Info().Str("userID", user.ID).Msg("user authorized for updating problem")
110138

111139
var req models.UpdateProblemRequest
112140
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
141+
c.Logger.Error().Err(err).Msg("invalid request body for updating problem")
113142
http.Error(w, "invalid request body", http.StatusBadRequest)
114143
return
115144
}
145+
c.Logger.Debug().
146+
Str("problemID", problemID).
147+
Str("userID", user.ID).
148+
Str("title_update", req.Title).
149+
RawJSON("description_json_update", req.DescriptionJSON).
150+
Msg("decoded update problem request body")
116151

117152
updatedProblem, err := c.ProblemModule.UpdateProblem(ctx, problemID, &req, user.ID)
118153
if err != nil {
119-
c.Logger.Error().Err(err).Msg("failed to update problem")
154+
c.Logger.Error().Err(err).
155+
Str("problemID", problemID).
156+
Str("userID", user.ID).
157+
Msg("failed to update problem via module")
120158
// This could be a not found error or an authorization error.
159+
if err.Error() == "problem not found" {
160+
http.Error(w, "problem not found", http.StatusNotFound)
161+
return
162+
}
163+
if err.Error() == "user not authorized to update this problem" {
164+
http.Error(w, "user not authorized", http.StatusForbidden)
165+
return
166+
}
121167
http.Error(w, err.Error(), http.StatusInternalServerError)
122168
return
123169
}
124170

171+
c.Logger.Info().Str("problemID", updatedProblem.ID.String()).Msg("successfully updated problem by ID")
125172
pkg.WriteJSONResponseWithLogger(w, http.StatusOK, updatedProblem, &c.Logger)
126173
}
127174

128175
// DeleteProblemByIDHandler handles DELETE /api/v1/problems/{id}
129176
func (c *ProblemController) DeleteProblemByIDHandler(w http.ResponseWriter, r *http.Request) {
130177
problemID := r.PathValue("id")
178+
c.Logger.Info().Str("problemID", problemID).Msg("received request to delete problem by ID")
179+
131180
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
132181
defer cancel()
133182

134183
user, ok := ctx.Value(middleware.UserContextKey).(*middleware.User)
135184
if !ok {
185+
c.Logger.Error().Msg("user not found in context for deleting problem")
136186
http.Error(w, "user not found in context", http.StatusUnauthorized)
137187
return
138188
}
189+
c.Logger.Info().Str("userID", user.ID).Msg("user authorized for deleting problem")
139190

140191
err := c.ProblemModule.DeleteProblem(ctx, problemID, user.ID)
141192
if err != nil {
142-
c.Logger.Error().Err(err).Msg("failed to delete problem")
193+
c.Logger.Error().Err(err).
194+
Str("problemID", problemID).
195+
Str("userID", user.ID).
196+
Msg("failed to delete problem via module")
143197
// This could be a not found error or an authorization error.
198+
if err.Error() == "problem not found" {
199+
http.Error(w, "problem not found", http.StatusNotFound)
200+
return
201+
}
202+
if err.Error() == "user not authorized to delete this problem" {
203+
http.Error(w, "user not authorized", http.StatusForbidden)
204+
return
205+
}
144206
http.Error(w, err.Error(), http.StatusInternalServerError)
145207
return
146208
}
147209

210+
c.Logger.Info().Str("problemID", problemID).Msg("successfully deleted problem by ID")
148211
w.WriteHeader(http.StatusNoContent)
149212
}

db/repository/problem_repository.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66

77
"github.com/Thanus-Kumaar/controller_microservice_v2/pkg/models"
8+
"github.com/jackc/pgx/v4"
89
"github.com/jackc/pgx/v4/pgxpool"
910
"github.com/rs/zerolog"
1011
)
@@ -38,6 +39,11 @@ func (r *problemRepository) WithLogger(logger zerolog.Logger) ProblemRepository
3839

3940
// CreateProblem inserts a new problem statement into the database.
4041
func (r *problemRepository) CreateProblem(ctx context.Context, problem *models.ProblemStatement) (*models.ProblemStatement, error) {
42+
r.logger.Info().
43+
Str("problemID", problem.ID.String()).
44+
Str("title", problem.Title).
45+
Msg("attempting to create new problem")
46+
4147
query := `
4248
INSERT INTO problem_statements (id, title, description_json, created_by, created_at)
4349
VALUES ($1, $2, $3, $4, $5)
@@ -66,11 +72,17 @@ func (r *problemRepository) CreateProblem(ctx context.Context, problem *models.P
6672
return nil, err
6773
}
6874

75+
r.logger.Info().
76+
Str("problemID", createdProblem.ID.String()).
77+
Msg("successfully created new problem")
78+
6979
return &createdProblem, nil
7080
}
7181

7282
// GetProblemByID retrieves a problem statement from the database by its ID.
7383
func (r *problemRepository) GetProblemByID(ctx context.Context, problemID string) (*models.ProblemStatement, error) {
84+
r.logger.Info().Str("problemID", problemID).Msg("attempting to get problem by ID")
85+
7486
query := `
7587
SELECT id, title, description_json, created_by, created_at
7688
FROM problem_statements
@@ -86,15 +98,22 @@ func (r *problemRepository) GetProblemByID(ctx context.Context, problemID string
8698
&problem.CreatedBy,
8799
&problem.CreatedAt,
88100
); err != nil {
101+
if err == pgx.ErrNoRows {
102+
r.logger.Warn().Str("problemID", problemID).Msg("problem not found")
103+
return nil, nil // Or return a custom error like models.ErrNotFound
104+
}
89105
r.logger.Error().Err(err).Str("problemID", problemID).Msg("failed to get problem by ID or scan row")
90106
return nil, err
91107
}
92108

109+
r.logger.Info().Str("problemID", problemID).Msg("successfully retrieved problem by ID")
93110
return &problem, nil
94111
}
95112

96113
// GetProblemsByUserID retrieves all problem statements for a given user.
97114
func (r *problemRepository) GetProblemsByUserID(ctx context.Context, userID string) ([]models.ProblemStatement, error) {
115+
r.logger.Info().Str("userID", userID).Msg("attempting to get problems by user ID")
116+
98117
query := `
99118
SELECT id, title, description_json, created_by, created_at
100119
FROM problem_statements
@@ -128,11 +147,21 @@ func (r *problemRepository) GetProblemsByUserID(ctx context.Context, userID stri
128147
return nil, err
129148
}
130149

150+
r.logger.Info().
151+
Str("userID", userID).
152+
Int("problem_count", len(problems)).
153+
Msg("successfully retrieved problems by user ID")
154+
131155
return problems, nil
132156
}
133157

134158
// UpdateProblem updates a problem statement in the database.
135159
func (r *problemRepository) UpdateProblem(ctx context.Context, problemID string, title string, description json.RawMessage) (*models.ProblemStatement, error) {
160+
r.logger.Info().
161+
Str("problemID", problemID).
162+
Str("title", title).
163+
Msg("attempting to update problem")
164+
136165
query := `
137166
UPDATE problem_statements
138167
SET title = $2, description_json = $3
@@ -153,15 +182,24 @@ func (r *problemRepository) UpdateProblem(ctx context.Context, problemID string,
153182
return nil, err
154183
}
155184

185+
r.logger.Info().
186+
Str("problemID", updatedProblem.ID.String()).
187+
Msg("successfully updated problem")
188+
156189
return &updatedProblem, nil
157190
}
158191

159192
// DeleteProblem deletes a problem statement from the database.
160193
func (r *problemRepository) DeleteProblem(ctx context.Context, problemID string) error {
194+
r.logger.Info().Str("problemID", problemID).Msg("attempting to delete problem")
195+
161196
query := `DELETE FROM problem_statements WHERE id = $1;`
162197
_, err := r.db.Exec(ctx, query, problemID)
163198
if err != nil {
164199
r.logger.Error().Err(err).Str("problemID", problemID).Msg("failed to delete problem")
200+
return err
165201
}
166-
return err
202+
203+
r.logger.Info().Str("problemID", problemID).Msg("successfully deleted problem")
204+
return nil
167205
}

0 commit comments

Comments
 (0)