mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-12-13 17:10:36 +00:00
Bun scan debugging
This commit is contained in:
parent
c696d502c5
commit
e3f7869c6d
@ -34,6 +34,42 @@ func (h *QueryDebugHook) AfterQuery(ctx context.Context, event *bun.QueryEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debugScanIntoStruct attempts to scan rows into a struct with detailed field-level logging
|
||||||
|
// This helps identify which specific field is causing scanning issues
|
||||||
|
func debugScanIntoStruct(rows interface{}, dest interface{}) error {
|
||||||
|
v := reflect.ValueOf(dest)
|
||||||
|
if v.Kind() != reflect.Ptr {
|
||||||
|
return fmt.Errorf("dest must be a pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
v = v.Elem()
|
||||||
|
if v.Kind() != reflect.Struct && v.Kind() != reflect.Slice {
|
||||||
|
return fmt.Errorf("dest must be pointer to struct or slice")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log the type being scanned into
|
||||||
|
logger.Debug("Debug scan into type: %s (kind: %s)", v.Type().Name(), v.Kind())
|
||||||
|
|
||||||
|
// If it's a struct, log all field types
|
||||||
|
if v.Kind() == reflect.Struct {
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
field := v.Type().Field(i)
|
||||||
|
fieldValue := v.Field(i)
|
||||||
|
|
||||||
|
// Log embedded fields specially
|
||||||
|
if field.Anonymous {
|
||||||
|
logger.Debug(" Embedded field [%d]: %s (type: %s, kind: %s)",
|
||||||
|
i, field.Name, field.Type, fieldValue.Kind())
|
||||||
|
} else {
|
||||||
|
logger.Debug(" Field [%d]: %s (type: %s, kind: %s, tag: %s)",
|
||||||
|
i, field.Name, field.Type, fieldValue.Kind(), field.Tag.Get("bun"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// BunAdapter adapts Bun to work with our Database interface
|
// BunAdapter adapts Bun to work with our Database interface
|
||||||
// This demonstrates how the abstraction works with different ORMs
|
// This demonstrates how the abstraction works with different ORMs
|
||||||
type BunAdapter struct {
|
type BunAdapter struct {
|
||||||
@ -52,6 +88,14 @@ func (b *BunAdapter) EnableQueryDebug() {
|
|||||||
logger.Info("Bun query debug mode enabled - all SQL queries will be logged")
|
logger.Info("Bun query debug mode enabled - all SQL queries will be logged")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnableDetailedScanDebug enables verbose logging of scan operations
|
||||||
|
// WARNING: This generates a LOT of log output. Use only for debugging specific issues.
|
||||||
|
func (b *BunAdapter) EnableDetailedScanDebug() {
|
||||||
|
logger.Info("Detailed scan debugging enabled - will log all field scanning operations")
|
||||||
|
// This is a flag that can be checked in scan operations
|
||||||
|
// Implementation would require modifying the scan logic
|
||||||
|
}
|
||||||
|
|
||||||
// DisableQueryDebug removes all query hooks
|
// DisableQueryDebug removes all query hooks
|
||||||
func (b *BunAdapter) DisableQueryDebug() {
|
func (b *BunAdapter) DisableQueryDebug() {
|
||||||
// Create a new DB without hooks
|
// Create a new DB without hooks
|
||||||
@ -676,6 +720,31 @@ func (b *BunSelectQuery) Scan(ctx context.Context, dest interface{}) (err error)
|
|||||||
func (b *BunSelectQuery) ScanModel(ctx context.Context) (err error) {
|
func (b *BunSelectQuery) ScanModel(ctx context.Context) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
// Enhanced panic recovery with model information
|
||||||
|
model := b.query.GetModel()
|
||||||
|
var modelInfo string
|
||||||
|
if model != nil && model.Value() != nil {
|
||||||
|
modelValue := model.Value()
|
||||||
|
modelInfo = fmt.Sprintf("Model type: %T", modelValue)
|
||||||
|
|
||||||
|
// Try to get the model's underlying struct type
|
||||||
|
v := reflect.ValueOf(modelValue)
|
||||||
|
if v.Kind() == reflect.Ptr {
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
if v.Kind() == reflect.Slice {
|
||||||
|
if v.Type().Elem().Kind() == reflect.Ptr {
|
||||||
|
modelInfo += fmt.Sprintf(", Slice of: %s", v.Type().Elem().Elem().Name())
|
||||||
|
} else {
|
||||||
|
modelInfo += fmt.Sprintf(", Slice of: %s", v.Type().Elem().Name())
|
||||||
|
}
|
||||||
|
} else if v.Kind() == reflect.Struct {
|
||||||
|
modelInfo += fmt.Sprintf(", Struct: %s", v.Type().Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlStr := b.query.String()
|
||||||
|
logger.Error("Panic in BunSelectQuery.ScanModel: %v. %s. SQL: %s", r, modelInfo, sqlStr)
|
||||||
err = logger.HandlePanic("BunSelectQuery.ScanModel", r)
|
err = logger.HandlePanic("BunSelectQuery.ScanModel", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -683,6 +752,17 @@ func (b *BunSelectQuery) ScanModel(ctx context.Context) (err error) {
|
|||||||
return fmt.Errorf("model is nil")
|
return fmt.Errorf("model is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optional: Enable detailed field-level debugging (set to true to debug)
|
||||||
|
const enableDetailedDebug = true
|
||||||
|
if enableDetailedDebug {
|
||||||
|
model := b.query.GetModel()
|
||||||
|
if model != nil && model.Value() != nil {
|
||||||
|
if err := debugScanIntoStruct(nil, model.Value()); err != nil {
|
||||||
|
logger.Warn("Debug scan inspection failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Execute the main query first
|
// Execute the main query first
|
||||||
err = b.query.Scan(ctx)
|
err = b.query.Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user