diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bdf1528a4..e00fdacdd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,10 +9,6 @@ on: name: Main jobs: - Pr: - if: github.event_name == 'pull_request' - uses: formancehq/gh-workflows/.github/workflows/pr-style.yml@main - Test_postgres: name: 'Test with PostgreSQL' runs-on: ubuntu-latest diff --git a/.github/workflows/template_goreleaser-build.yaml b/.github/workflows/template_goreleaser-build.yaml index 7e5213284..f6d454444 100644 --- a/.github/workflows/template_goreleaser-build.yaml +++ b/.github/workflows/template_goreleaser-build.yaml @@ -33,7 +33,7 @@ jobs: if: ${{ matrix.os == 'ubuntu-latest' }} uses: goreleaser/goreleaser-action@v4 with: - version: latest + version: v1.26.2 args: build --parallelism 4 --rm-dist --skip-validate --snapshot env: GITHUB_TOKEN: ${{ secrets.NUMARY_GITHUB_TOKEN }} @@ -42,7 +42,7 @@ jobs: if: ${{ matrix.os == 'macos-latest' }} uses: goreleaser/goreleaser-action@v4 with: - version: latest + version: v1.26.2 args: build -f .goreleaser-darwin.yml --parallelism 4 --rm-dist --skip-validate --snapshot env: GITHUB_TOKEN: ${{ secrets.NUMARY_GITHUB_TOKEN }} diff --git a/.github/workflows/template_goreleaser-release.yaml b/.github/workflows/template_goreleaser-release.yaml index 63dbf8bae..df235fdd5 100644 --- a/.github/workflows/template_goreleaser-release.yaml +++ b/.github/workflows/template_goreleaser-release.yaml @@ -44,7 +44,7 @@ jobs: SEGMENT_WRITE_KEY: ${{ secrets.SEGMENT_WRITE_KEY_OSS }} uses: goreleaser/goreleaser-action@v4 with: - version: latest + version: v1.26.2 args: release --rm-dist - name: Run GoReleaser for MacOS if: ${{ matrix.os == 'macos-latest' }} @@ -54,7 +54,7 @@ jobs: SEGMENT_WRITE_KEY: ${{ secrets.SEGMENT_WRITE_KEY_OSS }} uses: goreleaser/goreleaser-action@v4 with: - version: latest + version: v1.26.2 args: release -f .goreleaser-darwin.yml --rm-dist - uses: actions/cache@v2 with: diff --git a/pkg/api/apierrors/errors.go b/pkg/api/apierrors/errors.go index 82a91747d..ffaaca54f 100644 --- a/pkg/api/apierrors/errors.go +++ b/pkg/api/apierrors/errors.go @@ -19,6 +19,7 @@ import ( const ( ErrInternal = "INTERNAL" ErrConflict = "CONFLICT" + ErrTXID = "TXID_CONFLICT" ErrInsufficientFund = "INSUFFICIENT_FUND" ErrValidation = "VALIDATION" ErrContextCancelled = "CONTEXT_CANCELLED" @@ -64,6 +65,8 @@ func coreErrorToErrorCode(c *gin.Context, err error) (int, string, string) { ledger.IsScriptErrorWithCode(err, ErrScriptMetadataOverride): scriptErr := err.(*ledger.ScriptError) return http.StatusBadRequest, scriptErr.Code, EncodeLink(scriptErr.Message) + case ledger.IsTXIDError(err): + return http.StatusConflict, ErrTXID, "" case errors.Is(err, context.Canceled): return http.StatusInternalServerError, ErrContextCancelled, "" case storage.IsError(err): diff --git a/pkg/api/controllers/script_controller.go b/pkg/api/controllers/script_controller.go index 6598487ba..aec310113 100644 --- a/pkg/api/controllers/script_controller.go +++ b/pkg/api/controllers/script_controller.go @@ -48,6 +48,9 @@ func (ctl *ScriptController) PostScript(c *gin.Context) { case *ledger.ConflictError: code = apierrors.ErrConflict message = e.Error() + case *ledger.TXIDError: + code = apierrors.ErrTXID + message = e.Error() default: logging.FromContext(c.Request.Context()).Errorf( "internal errors executing script: %s", err) diff --git a/pkg/ledger/error.go b/pkg/ledger/error.go index af633e822..9f4e8a849 100644 --- a/pkg/ledger/error.go +++ b/pkg/ledger/error.go @@ -100,6 +100,25 @@ func IsConflictError(err error) bool { return errors.Is(err, &ConflictError{}) } +type TXIDError struct{} + +func (e TXIDError) Error() string { + return "conflict error on transaction id" +} + +func (e TXIDError) Is(err error) bool { + _, ok := err.(*TXIDError) + return ok +} + +func NewTXIDError() *TXIDError { + return &TXIDError{} +} + +func IsTXIDError(err error) bool { + return errors.Is(err, &TXIDError{}) +} + const ( ScriptErrorInsufficientFund = "INSUFFICIENT_FUND" ScriptErrorCompilationFailed = "COMPILATION_FAILED" diff --git a/pkg/ledger/execute_txsdata.go b/pkg/ledger/execute_txsdata.go index 1f0e218a4..ff0fe646f 100644 --- a/pkg/ledger/execute_txsdata.go +++ b/pkg/ledger/execute_txsdata.go @@ -162,6 +162,8 @@ func (l *Ledger) ExecuteTxsData(ctx context.Context, preview, checkBalances bool switch { case storage.IsErrorCode(err, storage.ConstraintFailed): return []core.ExpandedTransaction{}, NewConflictError() + case storage.IsErrorCode(err, storage.ConstraintTXID): + return []core.ExpandedTransaction{}, NewTXIDError() default: return []core.ExpandedTransaction{}, errors.Wrap(err, "committing transactions") diff --git a/pkg/storage/errors.go b/pkg/storage/errors.go index af07dfb74..698b7714b 100644 --- a/pkg/storage/errors.go +++ b/pkg/storage/errors.go @@ -13,6 +13,7 @@ type Code string const ( ConstraintFailed Code = "CONSTRAINT_FAILED" + ConstraintTXID Code = "CONSTRAINT_TXID" TooManyClient Code = "TOO_MANY_CLIENT" ) diff --git a/pkg/storage/sqlstorage/flavor.go b/pkg/storage/sqlstorage/flavor.go index 9e8c2da5d..cca392aef 100644 --- a/pkg/storage/sqlstorage/flavor.go +++ b/pkg/storage/sqlstorage/flavor.go @@ -56,6 +56,9 @@ func init() { if errors.As(err, &pgConnError) { switch pgConnError.Code { case "23505": + if pgConnError.ConstraintName == "transactions_id_key" { + return storage.NewError(storage.ConstraintTXID, err) + } return storage.NewError(storage.ConstraintFailed, err) case "53300": return storage.NewError(storage.TooManyClient, err) diff --git a/pkg/storage/sqlstorage/store_ledger_test.go b/pkg/storage/sqlstorage/store_ledger_test.go index 01ea008ec..1c88ab704 100644 --- a/pkg/storage/sqlstorage/store_ledger_test.go +++ b/pkg/storage/sqlstorage/store_ledger_test.go @@ -359,7 +359,7 @@ func testCommit(t *testing.T, store *sqlstorage.Store) { err = store.Commit(context.Background(), tx) require.Error(t, err) - require.True(t, storage.IsErrorCode(err, storage.ConstraintFailed)) + require.True(t, storage.IsErrorCode(err, storage.ConstraintTXID)) cursor, err := store.GetLogs(context.Background(), ledger.NewLogsQuery()) require.NoError(t, err)