diff --git a/api/api.go b/api/api.go index ba29d42a..358fb6e8 100644 --- a/api/api.go +++ b/api/api.go @@ -12,6 +12,7 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/config" "github.com/Gleipnir-Technology/nidus-sync/db" nhttp "github.com/Gleipnir-Technology/nidus-sync/http" + "github.com/Gleipnir-Technology/nidus-sync/lint" "github.com/Gleipnir-Technology/nidus-sync/platform" "github.com/Gleipnir-Technology/nidus-sync/platform/types" "github.com/Gleipnir-Technology/nidus-sync/resource" @@ -68,7 +69,10 @@ func handleClientIos(w http.ResponseWriter, r *http.Request, u platform.User) { var sinceStr string err := r.ParseForm() if err != nil { - renderShim(w, r, errRender(fmt.Errorf("Failed to parse GET form: %w", err))) + err = renderShim(w, r, errRender(fmt.Errorf("Failed to parse GET form: %w", err))) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } else { sinceStr = r.FormValue("since") @@ -80,14 +84,20 @@ func handleClientIos(w http.ResponseWriter, r *http.Request, u platform.User) { } else { since, err = parseTime(sinceStr) if err != nil { - renderShim(w, r, errRender(fmt.Errorf("Failed to parse 'since' value: %w", err))) + err = renderShim(w, r, errRender(fmt.Errorf("Failed to parse 'since' value: %w", err))) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } } csync, err := platform.ContentClientIos(r.Context(), u, since) if err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } @@ -102,7 +112,10 @@ func handleClientIos(w http.ResponseWriter, r *http.Request, u platform.User) { Since: since_used, } if err := renderShim(w, r, response); err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } } @@ -110,7 +123,10 @@ func handleClientIos(w http.ResponseWriter, r *http.Request, u platform.User) { func apiMosquitoSource(w http.ResponseWriter, r *http.Request, u platform.User) { bounds, err := parseBounds(r) if err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } @@ -119,7 +135,10 @@ func apiMosquitoSource(w http.ResponseWriter, r *http.Request, u platform.User) query.Limit = 100 sources, err := platform.MosquitoSourceQuery() if err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } @@ -128,14 +147,20 @@ func apiMosquitoSource(w http.ResponseWriter, r *http.Request, u platform.User) data = append(data, NewResponseMosquitoSource(s)) } if err := renderList(w, r, data); err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } } } func apiTrapData(w http.ResponseWriter, r *http.Request, u platform.User) { bounds, err := parseBounds(r) if err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } @@ -144,7 +169,10 @@ func apiTrapData(w http.ResponseWriter, r *http.Request, u platform.User) { query.Limit = 100 trap_data, err := platform.TrapDataQuery() if err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } @@ -153,14 +181,20 @@ func apiTrapData(w http.ResponseWriter, r *http.Request, u platform.User) { data = append(data, NewResponseTrapDatum(td)) } if err := renderList(w, r, data); err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } } } func apiServiceRequest(w http.ResponseWriter, r *http.Request, u platform.User) { bounds, err := parseBounds(r) if err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } query := db.NewGeoQuery() @@ -168,7 +202,10 @@ func apiServiceRequest(w http.ResponseWriter, r *http.Request, u platform.User) query.Limit = 100 requests, err := platform.ServiceRequestQuery() if err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } return } @@ -177,7 +214,10 @@ func apiServiceRequest(w http.ResponseWriter, r *http.Request, u platform.User) data = append(data, types.ServiceRequestFromModel(sr)) } if err := renderList(w, r, data); err != nil { - renderShim(w, r, errRender(err)) + err = renderShim(w, r, errRender(err)) + if err != nil { + http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError) + } } } @@ -226,7 +266,7 @@ func webhookFieldseeker(w http.ResponseWriter, r *http.Request) { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } - defer file.Close() + defer lint.LogOnErr(file.Close, "close request log") // Write timestamp timestamp := time.Now().Format("2006-01-02 15:04:05") @@ -238,10 +278,20 @@ func webhookFieldseeker(w http.ResponseWriter, r *http.Request) { } // Write request line - fmt.Fprintf(file, "%s %s %s\n", r.Method, r.RequestURI, r.Proto) + _, err = fmt.Fprintf(file, "%s %s %s\n", r.Method, r.RequestURI, r.Proto) + if err != nil { + log.Error().Err(err).Msg("writing response") + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } // Write all headers - fmt.Fprintf(file, "\nHeaders:\n") + _, err = fmt.Fprintf(file, "\nHeaders:\n") + if err != nil { + log.Error().Err(err).Msg("writing response") + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } for name, values := range r.Header { for _, value := range values { fmt.Fprintf(file, "%s: %s\n", name, value) @@ -249,11 +299,21 @@ func webhookFieldseeker(w http.ResponseWriter, r *http.Request) { } // Write body - fmt.Fprintf(file, "\nBody:\n") + _, err = fmt.Fprintf(file, "\nBody:\n") + if err != nil { + log.Error().Err(err).Msg("writing response") + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } body, err := io.ReadAll(r.Body) if err != nil { log.Printf("Error reading request body: %v", err) - fmt.Fprintf(file, "Error reading body: %v\n", err) + _, err = fmt.Fprintf(file, "Error reading body: %v\n", err) + if err != nil { + log.Error().Err(err).Msg("writing response") + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } } else { _, err = file.Write(body) if err != nil { diff --git a/api/handler.go b/api/handler.go index 6c585dc7..a90f3f69 100644 --- a/api/handler.go +++ b/api/handler.go @@ -94,7 +94,11 @@ func authenticatedHandlerJSON[T any](f handlerFunctionGetAuthenticated[T]) http. respondErrorStatus(w, nhttp.NewError("failed to marshal json: %w", err)) return } - w.Write(body) + _, err = w.Write(body) + if err != nil { + respondErrorStatus(w, nhttp.NewError("failed to write json: %w", err)) + return + } }) } @@ -124,7 +128,11 @@ func authenticatedHandlerJSONSlice[T any](f handlerFunctionGetSliceAuthenticated respondErrorStatus(w, nhttp.NewError("failed to marshal json: %w", err)) return } - w.Write(body) + _, err = w.Write(body) + if err != nil { + respondErrorStatus(w, nhttp.NewError("failed to write json: %w", err)) + return + } }) } func authenticatedHandlerJSONPost[RequestType any, ResponseType any](f handlerFunctionPostAuthenticated[RequestType, ResponseType]) http.Handler { @@ -146,7 +154,11 @@ func authenticatedHandlerJSONPost[RequestType any, ResponseType any](f handlerFu respondErrorStatus(w, nhttp.NewError("failed to marshal json: %w", err)) return } - w.Write(body) + _, err = w.Write(body) + if err != nil { + respondErrorStatus(w, nhttp.NewError("failed to write json: %w", err)) + return + } }) } diff --git a/label-studio/tasks_draft.go b/label-studio/tasks_draft.go index 0c838a0a..0a8b7d44 100644 --- a/label-studio/tasks_draft.go +++ b/label-studio/tasks_draft.go @@ -4,6 +4,8 @@ import ( "encoding/json" "fmt" "time" + + "github.com/Gleipnir-Technology/nidus-sync/lint" ) // DraftRequest represents the request body for creating a draft @@ -94,7 +96,7 @@ func (c *Client) CreateDraft(taskID int, draft *DraftRequest) (*Draft, error) { if err != nil { return nil, fmt.Errorf("failed to POST %s: %w", path, err) } - defer resp.Body.Close() + defer lint.LogOnErr(resp.Body.Close, "close response body") // Parse response var createdDraft Draft diff --git a/label-studio/tasks_update.go b/label-studio/tasks_update.go index 635eda63..da3eb31a 100644 --- a/label-studio/tasks_update.go +++ b/label-studio/tasks_update.go @@ -3,6 +3,8 @@ package labelstudio import ( "encoding/json" "fmt" + + "github.com/Gleipnir-Technology/nidus-sync/lint" ) type TaskResultValue struct { @@ -171,7 +173,7 @@ func (c *Client) TaskUpdate(taskID int, update *TaskUpdate) (*Task, error) { if err != nil { return nil, fmt.Errorf("failed to PATCH %s: %w", path, err) } - defer resp.Body.Close() + defer lint.LogOnErr(resp.Body.Close, "close response") // Parse response var updatedTask Task diff --git a/label-studio/users.go b/label-studio/users.go index 139e804c..5f2b8dcf 100644 --- a/label-studio/users.go +++ b/label-studio/users.go @@ -4,6 +4,8 @@ import ( "encoding/json" "fmt" "time" + + "github.com/Gleipnir-Technology/nidus-sync/lint" ) // User represents a user in Label Studio @@ -33,7 +35,7 @@ func (c *Client) ListUsers() ([]User, error) { if err != nil { return nil, fmt.Errorf("failed to GET /api/userls: %w", err) } - defer resp.Body.Close() + defer lint.LogOnErr(resp.Body.Close, "close response") // Parse response var users []User diff --git a/main.go b/main.go index d73581b1..3c807941 100644 --- a/main.go +++ b/main.go @@ -208,7 +208,10 @@ func main() { platform.WaitForExit() log.Info().Msg("Shutdown complete") - os.Stderr.Sync() + err = os.Stderr.Sync() + if err != nil { + panic("can't sync stderr") + } } func LoggerMiddleware(logger *zerolog.Logger) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { diff --git a/platform/email/template.go b/platform/email/template.go index c951aa3c..a15f5f08 100644 --- a/platform/email/template.go +++ b/platform/email/template.go @@ -99,7 +99,7 @@ func LoadTemplates() error { if err != nil { return fmt.Errorf("Failed to load report-notification-confirmation template ID: %s", err) } - tx.Commit(ctx) + lint.LogOnErrCtx(tx.Commit, ctx, "commit") return nil } diff --git a/platform/file/base.go b/platform/file/base.go index 2f8d3bf6..96b1c96d 100644 --- a/platform/file/base.go +++ b/platform/file/base.go @@ -7,6 +7,7 @@ import ( "os" "github.com/Gleipnir-Technology/nidus-sync/config" + "github.com/Gleipnir-Technology/nidus-sync/lint" "github.com/google/uuid" //"github.com/rs/zerolog/log" ) @@ -93,7 +94,7 @@ func writeFileContent(w http.ResponseWriter, image_path string) { } return } - defer file.Close() + defer lint.LogOnErr(file.Close, "close file") // Get file info for Content-Length header fileInfo, err := file.Stat() diff --git a/platform/file/image.go b/platform/file/image.go index 22635276..4deb722a 100644 --- a/platform/file/image.go +++ b/platform/file/image.go @@ -6,6 +6,7 @@ import ( "net/http" "os" + "github.com/Gleipnir-Technology/nidus-sync/lint" "github.com/google/uuid" "github.com/rs/zerolog/log" ) @@ -18,7 +19,7 @@ func ImageFileFromReader(collection Collection, uid uuid.UUID, body io.Reader) e if err != nil { return fmt.Errorf("Failed to create image file %s: %w", filepath, err) } - defer dst.Close() + defer lint.LogOnErr(dst.Close, "close dst file") // Copy rest of request body to file _, err = io.Copy(dst, body) diff --git a/platform/file/mailer.go b/platform/file/mailer.go index 310229e3..5e64ed30 100644 --- a/platform/file/mailer.go +++ b/platform/file/mailer.go @@ -5,6 +5,7 @@ import ( "io" "os" + "github.com/Gleipnir-Technology/nidus-sync/lint" "github.com/rs/zerolog/log" ) @@ -16,7 +17,7 @@ func MailerFromReader(public_id string, body io.Reader) error { if err != nil { return fmt.Errorf("Failed to create image file %s: %w", filepath, err) } - defer dst.Close() + defer lint.LogOnErr(dst.Close, "close dst file") // Copy rest of request body to file _, err = io.Copy(dst, body) diff --git a/platform/file/upload.go b/platform/file/upload.go index 14e2228d..e371fca1 100644 --- a/platform/file/upload.go +++ b/platform/file/upload.go @@ -7,6 +7,7 @@ import ( "mime/multipart" "net/http" + "github.com/Gleipnir-Technology/nidus-sync/lint" "github.com/google/uuid" "github.com/rs/zerolog/log" ) @@ -50,7 +51,7 @@ func saveFileUpload(headers *multipart.FileHeader, collection Collection) (uploa if err != nil { return upload, fmt.Errorf("Failed to open header: %w", err) } - defer file.Close() + defer lint.LogOnErr(file.Close, "close file") file_bytes, err := io.ReadAll(file) content_type := http.DetectContentType(file_bytes) diff --git a/platform/file/userfile.go b/platform/file/userfile.go index 077eca6c..093256d6 100644 --- a/platform/file/userfile.go +++ b/platform/file/userfile.go @@ -7,6 +7,7 @@ import ( "os" "github.com/Gleipnir-Technology/nidus-sync/config" + "github.com/Gleipnir-Technology/nidus-sync/lint" "github.com/google/uuid" "github.com/rs/zerolog/log" ) @@ -33,7 +34,7 @@ func FileContentWrite(body io.Reader, collection Collection, uid uuid.UUID) erro log.Error().Err(err).Str("filepath", filepath).Msg("Failed to create upload file") return fmt.Errorf("Failed to create upload file at %s: %v", filepath, err) } - defer dst.Close() + defer lint.LogOnErr(dst.Close, "close dst file") // Copy rest of request body to file _, err = io.Copy(dst, body) diff --git a/platform/mailer/mailer.go b/platform/mailer/mailer.go index f7c4ea8d..c537b082 100644 --- a/platform/mailer/mailer.go +++ b/platform/mailer/mailer.go @@ -9,6 +9,7 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/config" "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/Gleipnir-Technology/nidus-sync/lint" "github.com/Gleipnir-Technology/nidus-sync/lob" "github.com/Gleipnir-Technology/nidus-sync/platform/file" "github.com/Gleipnir-Technology/nidus-sync/platform/pdf" @@ -91,7 +92,7 @@ func ComplianceSend(ctx context.Context, row_id int32) error { if err != nil { return fmt.Errorf("start txn: %w", err) } - defer txn.Rollback(ctx) + defer lint.LogOnErrRollback(txn.Rollback, ctx, "rollback") mailer, err := models.CommsMailers.Insert(&models.CommsMailerSetter{ AddressID: omit.From(address.ID), Created: omit.From(time.Now()), @@ -113,7 +114,7 @@ func ComplianceSend(ctx context.Context, row_id int32) error { return fmt.Errorf("create crrm: %w", err) } log.Info().Int32("id", crrm.ID).Msg("Created compliance report request mailer") - txn.Commit(ctx) + lint.LogOnErrCtx(txn.Commit, ctx, "commit") return nil } diff --git a/platform/notification.go b/platform/notification.go index 7b815f4c..552fabc0 100644 --- a/platform/notification.go +++ b/platform/notification.go @@ -44,7 +44,10 @@ func ClearOauth(ctx context.Context, user *models.User) { models.UpdateWhere.Notifications.UserID.EQ(user.ID), setter.UpdateMod(), ) - updater.Exec(ctx, db.PGInstance.BobDB) + _, err := updater.Exec(ctx, db.PGInstance.BobDB) + if err != nil { + log.Error().Err(err).Msg("execute update") + } //user.UserNotifications( //models.SelectWhere.Notifications.Link.EQ(NotificationPathOauthReset), //).UpdateAll()