From e16c52544e7976019c4aa446f0f4317e6cab9d12 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Wed, 28 Oct 2026 23:38:57 +0700 Subject: [PATCH] up --- .../game_export_service/failure_test.go | 34 +++++++++++++++++++ .../services/game_export_service/service.go | 4 +++ .../game_package_service/validation.go | 15 +++++++- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 internal/services/game_export_service/failure_test.go diff --git a/internal/services/game_export_service/failure_test.go b/internal/services/game_export_service/failure_test.go new file mode 100644 index 0000000..d6bdd46 --- /dev/null +++ b/internal/services/game_export_service/failure_test.go @@ -0,0 +1,34 @@ +package game_export_service + +import ( + "errors" + "fmt" + "testing" + + "evening_detective_server/internal/services/game_package_service" +) + +func TestSafeFailure(t *testing.T) { + validation := &game_package_service.ValidationError{Reason: "некорректная команда"} + for _, tc := range []struct { + name string + err error + want string + }{ + {"validation", validation, "Не удалось подготовить автономный пакет: некорректная команда"}, + {"wrapped validation", fmt.Errorf("private path: %w", validation), "Не удалось подготовить автономный пакет: некорректная команда"}, + {"invalid package", errors.Join(game_package_service.ErrInvalidPackage, errors.New("private")), "Данные игры не подходят для автономного пакета."}, + {"technical", errors.New("private password"), "Не удалось подготовить пакет. Запустите экспорт повторно."}, + {"media", game_package_service.ErrMediaUnavailable, "Не удалось получить медиафайлы игры. Проверьте их доступность и повторите экспорт."}, + {"size", game_package_service.ErrLimitExceeded, "Пакет игры превышает допустимый размер."}, + } { + t.Run(tc.name, func(t *testing.T) { + if got := safeFailure(tc.err); got != tc.want { + t.Fatalf("got %q, want %q", got, tc.want) + } + }) + } + if !errors.Is(validation, game_package_service.ErrInvalidPackage) { + t.Fatal("validation must remain an invalid package error") + } +} diff --git a/internal/services/game_export_service/service.go b/internal/services/game_export_service/service.go index 0e49305..bf532a8 100644 --- a/internal/services/game_export_service/service.go +++ b/internal/services/game_export_service/service.go @@ -319,6 +319,10 @@ func safeFailure(err error) string { case errors.Is(err, game_package_service.ErrLimitExceeded): return "Пакет игры превышает допустимый размер." case errors.Is(err, game_package_service.ErrInvalidPackage): + var validation *game_package_service.ValidationError + if errors.As(err, &validation) { + return "Не удалось подготовить автономный пакет: " + validation.Reason + } return "Данные игры не подходят для автономного пакета." default: return "Не удалось подготовить пакет. Запустите экспорт повторно." diff --git a/internal/services/game_package_service/validation.go b/internal/services/game_package_service/validation.go index b3ad9ac..13cfac2 100644 --- a/internal/services/game_package_service/validation.go +++ b/internal/services/game_package_service/validation.go @@ -14,8 +14,21 @@ import ( "github.com/google/uuid" ) +// ValidationError contains a safe, user-facing package validation reason. +type ValidationError struct { + Reason string +} + +func (e *ValidationError) Error() string { + return ErrInvalidPackage.Error() + ": " + e.Reason +} + +func (e *ValidationError) Unwrap() error { + return ErrInvalidPackage +} + func invalid(reason string) error { - return fmt.Errorf("%w: %s", ErrInvalidPackage, reason) + return &ValidationError{Reason: reason} } func validateData(data *Data) error {