package bnwasm import ( "context" "errors" "testing" abiv1 "git.dev.alexdunmow.com/block/pluginsdk/abi/v1" "google.golang.org/protobuf/proto" ) // fakeHostErr mirrors *wasmguest.HostError's AbiErrorCode() method so the // transport's cross-boundary classification (mapTransportErr) can be exercised // natively, without importing the wasip1-only wasmguest package. type fakeHostErr struct { code abiv1.AbiErrorCode msg string } func (e *fakeHostErr) Error() string { return e.msg } func (e *fakeHostErr) AbiErrorCode() abiv1.AbiErrorCode { return e.code } // transportReturning builds a Transport whose every call fails with err. func transportReturning(err error) Transport { return func(_ string, _, _ proto.Message) error { return err } } func TestTransportMapsTxExpiredToSentinel(t *testing.T) { hostErr := &fakeHostErr{code: abiv1.AbiErrorCode_ABI_ERROR_CODE_TX_EXPIRED, msg: "host: tx handle expired"} tr := transportReturning(hostErr) ctx := context.Background() // Every db.* verb that crosses the transport must classify TX_EXPIRED. t.Run("query", func(t *testing.T) { _, err := tr.query(ctx, "SELECT 1", 7, nil) if !errors.Is(err, ErrTxExpired) { t.Fatalf("query err = %v, want ErrTxExpired", err) } }) t.Run("exec", func(t *testing.T) { _, err := tr.exec(ctx, "DELETE FROM t", 7, nil) if !errors.Is(err, ErrTxExpired) { t.Fatalf("exec err = %v, want ErrTxExpired", err) } }) t.Run("txBegin", func(t *testing.T) { _, err := tr.txBegin(ctx) if !errors.Is(err, ErrTxExpired) { t.Fatalf("txBegin err = %v, want ErrTxExpired", err) } }) t.Run("txCommit", func(t *testing.T) { if err := tr.txCommit(ctx, 7); !errors.Is(err, ErrTxExpired) { t.Fatalf("txCommit err = %v, want ErrTxExpired", err) } }) t.Run("txRollback", func(t *testing.T) { if err := tr.txRollback(ctx, 7); !errors.Is(err, ErrTxExpired) { t.Fatalf("txRollback err = %v, want ErrTxExpired", err) } }) } func TestTransportLeavesOtherAbiErrorsUntouched(t *testing.T) { hostErr := &fakeHostErr{code: abiv1.AbiErrorCode_ABI_ERROR_CODE_INTERNAL, msg: "boom"} tr := transportReturning(hostErr) _, err := tr.query(context.Background(), "SELECT 1", 0, nil) if errors.Is(err, ErrTxExpired) { t.Fatalf("non-tx-expired error was misclassified as ErrTxExpired: %v", err) } if !errors.Is(err, error(hostErr)) { t.Fatalf("original host error not preserved: %v", err) } }