veza/veza-backend-api/P1_RES_001_ERROR_PATTERN_MIGRATION_REPORT.md
2025-12-12 21:34:34 -05:00

9.2 KiB

P1-RES-001 — STANDARDISATION PATTERNS DE RÉPONSE D'ERREUR

Date: 2025-12-12
Objectif: Standardiser les patterns de réponse d'erreur en migrant TrackHandler vers RespondWithAppError


📋 RÉSUMÉ

Pattern cible identifié : RespondWithAppError (conforme ORIGIN_API_SPECIFICATION)
Helper créé : respondWithError() pour faciliter la migration
Endpoints critiques migrés : UploadTrack, GetUploadStatus, UpdateTrack, DeleteTrack
Tests ajoutés : Vérification de la forme des erreurs (structure JSON)
Compilation réussie : Aucune erreur de compilation


📁 FICHIERS MODIFIÉS

1. internal/core/track/handler.go

  • Imports ajoutés : apperrors, handlers pour utiliser RespondWithAppError et RespondSuccess
  • Helper respondWithError() créé (lignes 113-127) : Convertit HTTP status → ErrorCode → RespondWithAppError
  • Helper getUserID() mis à jour : Utilise maintenant RespondWithAppError au lieu de response.Unauthorized
  • Endpoints critiques migrés :
    1. UploadTrack : response.BadRequesth.respondWithError(), response.Createdhandlers.RespondSuccess()
    2. GetUploadStatus : response.BadRequest, response.InternalServerError, response.Success → format standardisé
    3. UpdateTrack : response.BadRequest, response.NotFound, response.Forbidden, response.InternalServerError, response.Success → format standardisé
    4. DeleteTrack : response.BadRequest, response.NotFound, response.Forbidden, response.InternalServerError, response.Success → format standardisé

2. internal/core/track/handler_error_format_test.go (nouveau)

  • TestTrackHandler_ErrorResponseFormat : Teste la structure JSON des erreurs (code, message, timestamp)
  • TestTrackHandler_SuccessResponseFormat : Teste la structure JSON des réponses de succès

🔍 IMPLÉMENTATION

Pattern cible : RespondWithAppError

Format standardisé :

{
  "success": false,
  "error": {
    "code": 2000,
    "message": "invalid track id",
    "timestamp": "2025-12-12T19:00:00Z",
    "request_id": "...",
    "details": []
  }
}

Helper créé

// respondWithError est un helper pour migrer vers RespondWithAppError
// MOD-P1-RES-001: Helper pour standardiser les réponses d'erreur
func (h *TrackHandler) respondWithError(c *gin.Context, httpStatus int, message string) {
	var errCode apperrors.ErrorCode
	switch httpStatus {
	case http.StatusBadRequest:
		errCode = apperrors.ErrCodeValidation
	case http.StatusUnauthorized:
		errCode = apperrors.ErrCodeUnauthorized
	case http.StatusForbidden:
		errCode = apperrors.ErrCodeForbidden
	case http.StatusNotFound:
		errCode = apperrors.ErrCodeNotFound
	case http.StatusInternalServerError:
		errCode = apperrors.ErrCodeInternal
	default:
		errCode = apperrors.ErrCodeInternal
	}
	handlers.RespondWithAppError(c, apperrors.New(errCode, message))
}

Pattern de remplacement

Avant (format simple) :

response.BadRequest(c, "invalid track id")
// → {"success": false, "error": "invalid track id"}

Après (format structuré) :

h.respondWithError(c, http.StatusBadRequest, "invalid track id")
// → {"success": false, "error": {"code": 2000, "message": "invalid track id", "timestamp": "...", ...}}

📊 MATRICE AVANT/APRÈS

Endpoint Méthode Avant (Pattern) Après (Pattern) Status HTTP Format erreur
POST /tracks UploadTrack response.BadRequest() h.respondWithError() 400 Structuré
POST /tracks UploadTrack response.Created() handlers.RespondSuccess() 201 Standardisé
GET /tracks/:id/progress GetUploadStatus response.BadRequest() h.respondWithError() 400 Structuré
GET /tracks/:id/progress GetUploadStatus response.Success() handlers.RespondSuccess() 200 Standardisé
PUT /tracks/:id UpdateTrack response.BadRequest() h.respondWithError() 400 Structuré
PUT /tracks/:id UpdateTrack response.NotFound() h.respondWithError() 404 Structuré
PUT /tracks/:id UpdateTrack response.Forbidden() h.respondWithError() 403 Structuré
PUT /tracks/:id UpdateTrack response.Success() handlers.RespondSuccess() 200 Standardisé
DELETE /tracks/:id DeleteTrack response.BadRequest() h.respondWithError() 400 Structuré
DELETE /tracks/:id DeleteTrack response.NotFound() h.respondWithError() 404 Structuré
DELETE /tracks/:id DeleteTrack response.Forbidden() h.respondWithError() 403 Structuré
DELETE /tracks/:id DeleteTrack response.Success() handlers.RespondSuccess() 200 Standardisé

🧪 PREUVES (TESTS)

Tests unitaires

go test ./internal/core/track -run TestTrackHandler_ErrorResponseFormat -v -count=1

Résultat : Tests passent (vérification de la structure JSON)

Test 1 : Format des erreurs

TestTrackHandler_ErrorResponseFormat
  • Vérifie que les erreurs suivent le format RespondWithAppError
  • Vérifie la présence des champs : code, message, timestamp
  • Vérifie que code est un nombre positif
  • Vérifie que message est une string non vide
  • Vérifie que timestamp est au format RFC3339

Test 2 : Format des réponses de succès

TestTrackHandler_SuccessResponseFormat
  • Vérifie que les réponses de succès suivent le format RespondSuccess
  • Vérifie la présence des champs : success, data
  • Vérifie que success est true

Tests complets

go test ./internal/core/track -v -count=1

Résultat : Tous les tests passent


📊 COMPARAISON DES PATTERNS

Pattern internal/response (ancien)

Format :

{
  "success": false,
  "error": "invalid track id"
}

Avantages :

  • Simple et direct
  • Facile à utiliser

Inconvénients :

  • Pas de code d'erreur standardisé
  • Pas de timestamp
  • Pas de détails structurés
  • Incohérent avec ProfileHandler

Pattern RespondWithAppError (nouveau)

Format :

{
  "success": false,
  "error": {
    "code": 2000,
    "message": "invalid track id",
    "timestamp": "2025-12-12T19:00:00Z",
    "request_id": "...",
    "details": []
  }
}

Avantages :

  • Format structuré et standardisé
  • Code d'erreur pour traitement programmatique
  • Timestamp pour debugging
  • Request ID pour traçabilité
  • Détails pour erreurs de validation
  • Cohérent avec ProfileHandler et autres handlers
  • Conforme à ORIGIN_API_SPECIFICATION

VALIDATION

Compilation

go build ./internal/core/track/...

Résultat : Compilation réussie

Tests unitaires

go test ./internal/core/track -run TestTrackHandler_ErrorResponseFormat -v

Résultat : Tests passent

Tests complets

go test ./internal/core/track -v -count=1

Résultat : Tous les tests passent

Vérification cohérence

Les endpoints suivants utilisent maintenant le même format que ProfileHandler :

  • POST /tracks (UploadTrack)
  • GET /tracks/:id/progress (GetUploadStatus)
  • PUT /tracks/:id (UpdateTrack)
  • DELETE /tracks/:id (DeleteTrack)

🎯 OBJECTIFS ATTEINTS

  • Pattern cible identifié : RespondWithAppError (conforme ORIGIN_API_SPECIFICATION)
  • Endpoints critiques migrés : 4 endpoints les plus exposés
  • Helper créé : respondWithError() pour faciliter la migration
  • Tests ajoutés : Vérification de la structure JSON des erreurs
  • Cohérence améliorée : TrackHandler et ProfileHandler utilisent maintenant le même format

📋 COMMANDES DE VALIDATION

Compilation

go build ./internal/core/track/...

Tests spécifiques

go test ./internal/core/track -run TestTrackHandler_ErrorResponseFormat -v -count=1
go test ./internal/core/track -run TestTrackHandler_SuccessResponseFormat -v -count=1

Tests complets

go test ./internal/core/track -v -count=1

📝 ENDPOINTS DÉSORMAIS COHÉRENTS

Les endpoints suivants utilisent maintenant le format standardisé RespondWithAppError / RespondSuccess :

  1. POST /tracks (UploadTrack) - Endpoint très exposé
  2. GET /tracks/:id/progress (GetUploadStatus) - Utilisé fréquemment
  3. PUT /tracks/:id (UpdateTrack) - Modification critique
  4. DELETE /tracks/:id (DeleteTrack) - Suppression critique

Ces endpoints sont maintenant cohérents avec :

  • ProfileHandler (GetProfile, UpdateProfile, etc.)
  • PlaylistHandler (utilise déjà RespondWithAppError)
  • AuthHandler (utilise déjà RespondWithAppError)

Statut final : P1-RES-001 IMPLÉMENTÉ ET VALIDÉ

Note : La migration complète de tous les endpoints TrackHandler vers RespondWithAppError peut être effectuée progressivement. Les 4 endpoints critiques ont été migrés pour supprimer l'incohérence observable côté clients.