mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-08 14:26:28 +00:00
fix(pgsql): return subquery preload errors instead of logging and continuing
This commit is contained in:
@@ -1208,7 +1208,7 @@ func (p *PgSQLSelectQuery) applySubqueryPreloads(ctx context.Context, dest inter
|
|||||||
for i := 0; i < destValue.Len(); i++ {
|
for i := 0; i < destValue.Len(); i++ {
|
||||||
elem := destValue.Index(i)
|
elem := destValue.Index(i)
|
||||||
if err := p.loadPreloadsForRecord(ctx, elem, subqueryPreloads); err != nil {
|
if err := p.loadPreloadsForRecord(ctx, elem, subqueryPreloads); err != nil {
|
||||||
logger.Warn("Failed to load preloads for record %d: %v", i, err)
|
return fmt.Errorf("record %d: %w", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -1256,7 +1256,9 @@ func (p *PgSQLSelectQuery) loadPreloadsForRecord(ctx context.Context, record ref
|
|||||||
// Build and execute the preload query
|
// Build and execute the preload query
|
||||||
err := p.executePreloadQuery(ctx, field, meta, fkValue, preload)
|
err := p.executePreloadQuery(ctx, field, meta, fkValue, preload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("Failed to execute preload query for '%s': %v", preload.relation, err)
|
// Inside a transaction a failed statement aborts it, so carrying on would
|
||||||
|
// only turn into a misleading "transaction is aborted" on the next query.
|
||||||
|
return fmt.Errorf("preload %s: %w", preload.relation, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/DATA-DOG/go-sqlmock"
|
||||||
|
|
||||||
|
"github.com/bitechdev/ResolveSpec/pkg/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type preloadChild struct {
|
||||||
|
ID int `db:"id"`
|
||||||
|
UserID int `db:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (preloadChild) TableName() string { return "children" }
|
||||||
|
|
||||||
|
type preloadParent struct {
|
||||||
|
ID int `db:"id"`
|
||||||
|
Children []preloadChild `bun:"rel:has-many,join:ID=user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (preloadParent) TableName() string { return "parents" }
|
||||||
|
|
||||||
|
func TestSubqueryPreloadErrorIsReturned(t *testing.T) {
|
||||||
|
for name, dest := range map[string]interface{}{
|
||||||
|
"slice": &[]preloadParent{},
|
||||||
|
"single": &preloadParent{},
|
||||||
|
} {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
db, mock, err := sqlmock.New()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
mock.ExpectBegin()
|
||||||
|
mock.ExpectQuery(`FROM parents`).WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1))
|
||||||
|
mock.ExpectQuery(`FROM children`).WillReturnError(errors.New("boom"))
|
||||||
|
mock.ExpectRollback()
|
||||||
|
|
||||||
|
err = NewPgSQLAdapter(db).RunInTransaction(context.Background(), func(tx common.Database) error {
|
||||||
|
return tx.NewSelect().Model(&preloadParent{}).PreloadRelation("Children").Scan(context.Background(), dest)
|
||||||
|
})
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "preload Children") {
|
||||||
|
t.Fatalf("expected the preload error, got %v", err)
|
||||||
|
}
|
||||||
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user