errors.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. // Package handlers
  2. package handlers
  3. import (
  4. "encoding/json"
  5. "log/slog"
  6. "net/http"
  7. )
  8. const maxRequestBodySize = 1 << 20 // 1 MB
  9. // AppEnv is set at startup to control error detail exposure
  10. var AppEnv string
  11. // writeJSON writes a JSON response
  12. func writeJSON(w http.ResponseWriter, status int, v interface{}) {
  13. w.Header().Set("Content-Type", "application/json")
  14. w.WriteHeader(status)
  15. json.NewEncoder(w).Encode(v)
  16. }
  17. // writeError writes an error response.
  18. // In production, internal server errors return a generic message.
  19. // In development, the actual error message is returned.
  20. func writeError(w http.ResponseWriter, status int, msg string, err error) {
  21. if err != nil {
  22. slog.Error("handler error", "status", status, "error", err)
  23. }
  24. if status == http.StatusInternalServerError && AppEnv == "production" {
  25. msg = "internal server error"
  26. }
  27. writeJSON(w, status, map[string]string{"error": msg})
  28. }
  29. // writeValidationError writes a validation error response (422).
  30. // In production, hides internal field names and rules from the client.
  31. func writeValidationError(w http.ResponseWriter, err error) {
  32. details := err.Error()
  33. if AppEnv == "production" {
  34. details = "validation failed"
  35. }
  36. writeJSON(w, http.StatusUnprocessableEntity, map[string]interface{}{
  37. "error": "validation failed",
  38. "details": details,
  39. })
  40. }