[FIX] Register: Améliorer logs d'erreur pour diagnostic

- Ajouter logs détaillés dans service.go (erreur PostgreSQL complète)
- Ajouter logs détaillés dans handler (erreur complète avant encapsulation)
- Capturer type d'erreur, message, et contexte
- Gérer erreurs CHECK constraint, ENUM manquant, timeout
- Permettre identification précise de l'erreur réelle
This commit is contained in:
senke 2025-12-26 23:25:40 +01:00
parent 08596eda71
commit 4e0d436bf9
2 changed files with 53 additions and 7 deletions

View file

@ -230,14 +230,23 @@ func (s *AuthService) Register(ctx context.Context, email, username, password st
fmt.Printf("========== REGISTER: DB INSERT ERROR ==========\n")
fmt.Printf(">>> ERROR: %v\n", result.Error)
fmt.Printf(">>> ERROR TYPE: %T\n", result.Error)
fmt.Printf(">>> ERROR STRING: %s\n", result.Error.Error())
fmt.Printf(">>> ROWS AFFECTED: %d\n", result.RowsAffected)
fmt.Printf("===============================================\n")
// Log l'erreur complète pour diagnostic
err := result.Error
s.logger.Error("Failed to create user in database - full error details",
errMsg := err.Error()
errType := fmt.Sprintf("%T", err)
s.logger.Error("Failed to create user in database - FULL ERROR DETAILS",
zap.Error(err),
zap.String("error_type", errType),
zap.String("error_string", errMsg),
zap.String("email", email),
zap.String("username", username),
zap.String("slug", slug),
zap.String("role", user.Role),
zap.String("user_id", user.ID.String()),
zap.Any("user_fields", map[string]interface{}{
"is_banned": user.IsBanned,
@ -250,22 +259,46 @@ func (s *AuthService) Register(ctx context.Context, email, username, password st
}),
)
// Vérifier les erreurs PostgreSQL spécifiques
// Contrainte CHECK
if strings.Contains(errMsg, "violates check constraint") {
if strings.Contains(errMsg, "chk_users_username_format") {
s.logger.Warn("Registration failed: username format invalid", zap.String("username", username))
return nil, nil, errors.New("username format invalid: must be 3-30 alphanumeric characters")
}
if strings.Contains(errMsg, "chk_users_email_format") {
s.logger.Warn("Registration failed: email format invalid", zap.String("email", email))
return nil, nil, errors.New("email format invalid")
}
// Autre contrainte CHECK
s.logger.Warn("Registration failed: check constraint violation", zap.Error(err))
return nil, nil, fmt.Errorf("validation failed: %w", err)
}
// Type ENUM manquant
if strings.Contains(errMsg, "does not exist") && strings.Contains(errMsg, "user_role") {
s.logger.Error("Registration failed: user_role enum missing from database")
return nil, nil, fmt.Errorf("database schema error: user_role enum missing - run migrations")
}
// Timeout
if strings.Contains(errMsg, "context deadline exceeded") || strings.Contains(errMsg, "timeout") {
s.logger.Warn("Registration failed: database operation timed out")
return nil, nil, fmt.Errorf("database operation timed out: %w", err)
}
// PostgreSQL error code 23505 is unique_violation
// We check for specific constraint names if possible, or fallback to generic "duplicate"
errMsg := err.Error()
if strings.Contains(errMsg, "users_email_key") || strings.Contains(errMsg, "idx_users_email") {
s.logger.Warn("Registration failed: email already exists", zap.String("email", email))
return nil, nil, services.ErrUserAlreadyExists
}
if strings.Contains(errMsg, "users_username_key") || strings.Contains(errMsg, "idx_users_username") {
s.logger.Warn("Registration failed: username already exists", zap.String("username", username))
// We can return the same error or a more specific one if needed
return nil, nil, errors.New("username already exists")
}
if strings.Contains(errMsg, "users_slug_key") || strings.Contains(errMsg, "idx_users_slug") {
s.logger.Warn("Registration failed: slug collision", zap.String("slug", user.Slug))
// In a real robust system, we would retry with a suffix here
// For now, fail explicitly so the user knows
return nil, nil, errors.New("username unavailable (slug collision)")
}
@ -276,7 +309,13 @@ func (s *AuthService) Register(ctx context.Context, email, username, password st
}
// Pour toutes les autres erreurs, retourner l'erreur originale avec contexte
return nil, nil, fmt.Errorf("database error: %w", err)
// IMPORTANT: Inclure l'erreur complète pour diagnostic
s.logger.Error("Registration failed: unknown database error",
zap.Error(err),
zap.String("error_type", errType),
zap.String("error_string", errMsg),
)
return nil, nil, fmt.Errorf("database error [%s]: %w", errType, err)
}
fmt.Printf("========== REGISTER: DB INSERT SUCCESS ==========\n")

View file

@ -175,7 +175,14 @@ func Register(authService *auth.AuthService, sessionService *services.SessionSer
case services.IsWeakPassword(err):
RespondWithAppError(c, apperrors.NewValidationError("Password does not meet requirements"))
default:
commonHandler.logger.Error("Registration failed", zap.Error(err))
// Log l'erreur complète pour diagnostic
commonHandler.logger.Error("Registration failed - FULL ERROR",
zap.Error(err),
zap.String("error_type", fmt.Sprintf("%T", err)),
zap.String("error_string", err.Error()),
zap.String("email", req.Email),
zap.String("username", req.Username),
)
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to create user", err))
}
return