# Package-level mutable state: var AppEnv **Контекст**: В `backend/internal/handlers/errors.go:13` объявлена глобальная переменная `var AppEnv string`, которая устанавливается из `cmd/api/main.go:68`. Используется для контроля раскрытия деталей ошибок в production. ## Проблема ```go // handlers/errors.go — ❌ package-level mutable state var AppEnv string func writeError(w http.ResponseWriter, status int, msg string, err error) { if status == http.StatusInternalServerError && AppEnv == "production" { msg = "internal server error" } writeJSON(w, status, map[string]string{"error": msg}) } ``` ```go // cmd/api/main.go:68 — установка глобальной переменной handlers.AppEnv = cfg.AppEnv ``` **Антипаттерн**: 1. **Невозможно тестировать** — хендлеры зависят от внешнего состояния. Для теста `writeError` в production-режиме нужно установить `AppEnv = "production"`, а потом сбросить. При параллельных тестах — race condition. 2. **Неявная связь** — любой хендлер может изменить `AppEnv` в любой момент. Нет гарантии консистентности. 3. **Нарушение DI** — вместо явной передачи зависимости — глобальный мутабельный синглтон. ## Решение Передавать `isProd` через конструктор хендлера (как уже сделано в `AuthHandler`): ```go type PlaceHandler struct { placeSvc *services.PlaceService isProd bool // ✅ явная зависимость } func NewPlaceHandler(placeSvc *services.PlaceService, isProd bool) *PlaceHandler { return &PlaceHandler{placeSvc: placeSvc, isProd: isProd} } func (h *PlaceHandler) writeError(w http.ResponseWriter, status int, msg string, err error) { if status == http.StatusInternalServerError && h.isProd { msg = "internal server error" } writeJSON(w, status, map[string]string{"error": msg}) } ``` ## Trade-offs | Подход | Плюсы | Минусы | |---|---|---| | **DI через конструктор** (рекомендую) | Тестируемо, явно, потокобезопасно | Нужно менять все хендлеры | | **Context values** | Не меняет сигнатуры хендлеров | Неявно, `.Value()` без проверки типа | | **Оставить как есть (status quo)** | Нет работы | Нет тестов, race condition | ## Связанные заметки - [[backend-validation]] — где используется `AppEnv` - [[architecture-overview]] — таблица P0 - [[MOC-backend-patterns]] ## Источник Code review PhotoPlaces 2026-06. Найдено в `handlers/errors.go:13`. ## Теги #architecture #anti-pattern #testing #golang #clean-code