go-gorm/playground#841
`package extsystem_test
import (
"context"
"os"
"testing"
"github.com/stretchr/testify/require"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
// https://github.com/go-gorm/gorm/blob/master/callbacks/query.go#L24
// here such a fix handles the panic in gorm
// defer func() {
// r := recover()
// if r == nil {
// db.AddError(rows.Close())
// } else {
// db.AddError(fmt.Errorf("%v", r)) //nolint:err113
// }
// }()
// TestPanicInGorm gorm code freezes if there is a panic in scan
func TestPanicInGorm(t *testing.T) {
t.Helper()
t.Parallel()
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
ctx := context.Background()
err = db.WithContext(ctx).Exec("CREATE TABLE table_test (payload bytea)").Error
require.NoError(t, err)
data := TestStruct{
Payload: []byte("test"),
}
err = db.WithContext(ctx).Create(&data).Error
require.NoError(t, err)
var dbModel TestStruct
// there's a panic in Scan and a potential hang in gorm
err = db.WithContext(ctx).First(&dbModel).Error
require.Error(t, err)
t.Log("finish")
}
type TestStruct struct {
Payload OwnerType gorm:"column:payload"
}
func (*TestStruct) TableName() string {
return "table_test"
}
type OwnerType []byte
func (s *OwnerType) Scan(value interface{}) error {
data, ok := value.([]byte)
if !ok {
*s = OwnerType{}
return nil
}
// panic
data = data[:-len(data)]
*s = data
return nil
}
`
go-gorm/playground#841
`package extsystem_test
import (
"context"
"os"
"testing"
)
// https://github.com/go-gorm/gorm/blob/master/callbacks/query.go#L24
// here such a fix handles the panic in gorm
// defer func() {
// r := recover()
// if r == nil {
// db.AddError(rows.Close())
// } else {
// db.AddError(fmt.Errorf("%v", r)) //nolint:err113
// }
// }()
// TestPanicInGorm gorm code freezes if there is a panic in scan
func TestPanicInGorm(t *testing.T) {
t.Helper()
t.Parallel()
}
type TestStruct struct {
Payload OwnerType
gorm:"column:payload"}
func (*TestStruct) TableName() string {
return "table_test"
}
type OwnerType []byte
func (s *OwnerType) Scan(value interface{}) error {
data, ok := value.([]byte)
if !ok {
*s = OwnerType{}
return nil
}
}
`