Skip to content

Commit

Permalink
feat: add new error code for txid conflicts (#493)
Browse files Browse the repository at this point in the history
* feat: add new error code for txid conflicts

* fix: test on txid conflict

Signed-off-by: Clément Salaün <salaun.clement@gmail.com>

* ci: Update

* ci: Update

---------

Signed-off-by: Clément Salaün <salaun.clement@gmail.com>
Co-authored-by: Maxence Maireaux <maxence@maireaux.fr>
  • Loading branch information
altitude and flemzord committed Aug 27, 2024
1 parent acbd8bd commit 5c08eae
Show file tree
Hide file tree
Showing 10 changed files with 36 additions and 9 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/template_goreleaser-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand All @@ -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 }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/template_goreleaser-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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' }}
Expand All @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/apierrors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
const (
ErrInternal = "INTERNAL"
ErrConflict = "CONFLICT"
ErrTXID = "TXID_CONFLICT"
ErrInsufficientFund = "INSUFFICIENT_FUND"
ErrValidation = "VALIDATION"
ErrContextCancelled = "CONTEXT_CANCELLED"
Expand Down Expand Up @@ -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):
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/controllers/script_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions pkg/ledger/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 2 additions & 0 deletions pkg/ledger/execute_txsdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
1 change: 1 addition & 0 deletions pkg/storage/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type Code string

const (
ConstraintFailed Code = "CONSTRAINT_FAILED"
ConstraintTXID Code = "CONSTRAINT_TXID"
TooManyClient Code = "TOO_MANY_CLIENT"
)

Expand Down
3 changes: 3 additions & 0 deletions pkg/storage/sqlstorage/flavor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion pkg/storage/sqlstorage/store_ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 5c08eae

Please sign in to comment.