This commit is contained in:
2026-10-11 15:21:54 +07:00
parent 5da08f6916
commit 504b49f7cc
6 changed files with 37 additions and 6 deletions
+16 -2
View File
@@ -19,6 +19,14 @@ var (
ErrRetry = errors.New("возврат временно недоступен; повторите попытку")
)
// ConflictError carries a safe explanation for the upload interface.
type ConflictError struct{ Reason string }
func (e *ConflictError) Error() string {
return "Конфликт пакета результатов: " + e.Reason
}
func (e *ConflictError) Unwrap() error { return ErrConflict }
// Return is retained even after the source game is deleted.
type Return struct {
PackageID string
@@ -59,8 +67,14 @@ func (r *GameReturnsRepo) Transaction(ctx context.Context, apply func(pgx.Tx) (*
switch pgErr.Code {
case "40001", "40P01":
continue
case "23505", "23503", "23514", "22001", "22003", "2200H":
return nil, ErrConflict
case "23505":
return nil, &ConflictError{Reason: "идентификатор или уникальные данные уже заняты (например, хеш билета)."}
case "23503":
return nil, &ConflictError{Reason: "отсутствует связанная запись, необходимая для загрузки результатов."}
case "23514", "22001", "22003":
return nil, &ConflictError{Reason: "значение в пакете не соответствует ограничениям базы данных."}
case "2200H":
return nil, &ConflictError{Reason: "исчерпан диапазон идентификаторов базы данных."}
}
}
return nil, err
+2 -2
View File
@@ -32,7 +32,7 @@ func Write(ctx context.Context, tx pgx.Tx, gameID int, data []byte) error {
return err
}
if collision {
return ErrConflict
return &ConflictError{Reason: "идентификатор команды или билета уже используется в другой игре."}
}
for _, query := range []string{
`DELETE FROM actions a
@@ -237,7 +237,7 @@ func Write(ctx context.Context, tx pgx.Tx, gameID int, data []byte) error {
return err
}
if maximum >= 2147483647 {
return ErrConflict
return &ConflictError{Reason: "идентификатор команды достиг предела допустимого диапазона."}
}
advanceCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()