Initial commit
This commit is contained in:
commit
02a6dabcfb
62 files changed
+15751
No files matched your search
@@ -0,0 +1,103 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// SchemaMismatch represents a mismatch between expected and actual API response
|
||||
type SchemaMismatch struct {
|
||||
ModelName string
|
||||
MissingFields []string
|
||||
UnknownFields []string
|
||||
UnknownValues map[string]any
|
||||
Endpoint string
|
||||
LibraryVersion string
|
||||
}
|
||||
|
||||
func (sm *SchemaMismatch) Describe() string {
|
||||
var parts []string
|
||||
parts = append(parts, fmt.Sprintf("Model: %s", sm.ModelName))
|
||||
if len(sm.MissingFields) > 0 {
|
||||
parts = append(parts, fmt.Sprintf("Missing fields: %v", sm.MissingFields))
|
||||
}
|
||||
if len(sm.UnknownFields) > 0 {
|
||||
parts = append(parts, fmt.Sprintf("Unknown fields: %v", sm.UnknownFields))
|
||||
}
|
||||
if len(sm.UnknownValues) > 0 {
|
||||
parts = append(parts, fmt.Sprintf("Unknown field structures: %v", sm.UnknownValues))
|
||||
}
|
||||
parts = append(parts, fmt.Sprintf("Endpoint: %s", sm.Endpoint))
|
||||
parts = append(parts, fmt.Sprintf("Library version: %s", sm.LibraryVersion))
|
||||
return strings.Join(parts, "\n")
|
||||
}
|
||||
|
||||
// SchemaMismatchHandler is a callback for handling schema mismatches
|
||||
type SchemaMismatchHandler func(*SchemaMismatch)
|
||||
|
||||
// SchemaMismatchConfig holds configuration for schema mismatch handling
|
||||
type SchemaMismatchConfig struct {
|
||||
ReportUnknownFields bool
|
||||
Strict bool
|
||||
OnSchemaMismatch SchemaMismatchHandler
|
||||
}
|
||||
|
||||
// DefaultSchemaMismatchConfig returns the default configuration
|
||||
func DefaultSchemaMismatchConfig() SchemaMismatchConfig {
|
||||
return SchemaMismatchConfig{
|
||||
ReportUnknownFields: false,
|
||||
Strict: false,
|
||||
OnSchemaMismatch: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// ReportSchemaMismatch reports a schema mismatch according to config
|
||||
func ReportSchemaMismatch(config SchemaMismatchConfig, modelName, endpoint string, missingFields, unknownFields []string, unknownValues map[string]any) error {
|
||||
mismatch := &SchemaMismatch{
|
||||
ModelName: modelName,
|
||||
MissingFields: missingFields,
|
||||
UnknownFields: unknownFields,
|
||||
UnknownValues: unknownValues,
|
||||
Endpoint: endpoint,
|
||||
LibraryVersion: "go-port-0.1.0",
|
||||
}
|
||||
|
||||
if config.OnSchemaMismatch != nil {
|
||||
config.OnSchemaMismatch(mismatch)
|
||||
return nil
|
||||
}
|
||||
|
||||
msg := mismatch.Describe()
|
||||
if config.Strict {
|
||||
return fmt.Errorf("schema mismatch: %s", msg)
|
||||
}
|
||||
|
||||
log.Printf("WARNING: Schema mismatch for %s:\n%s", modelName, msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SchemaMismatchTracker tracks reported mismatches to avoid duplicates
|
||||
type SchemaMismatchTracker struct {
|
||||
mu sync.Mutex
|
||||
reported map[string]bool
|
||||
}
|
||||
|
||||
func NewSchemaMismatchTracker() *SchemaMismatchTracker {
|
||||
return &SchemaMismatchTracker{
|
||||
reported: make(map[string]bool),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *SchemaMismatchTracker) ShouldReport(modelName string, fields []string) bool {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
key := modelName + ":" + strings.Join(fields, ",")
|
||||
if t.reported[key] {
|
||||
return false
|
||||
}
|
||||
t.reported[key] = true
|
||||
return true
|
||||
}
|
||||
Reference in new issue
Block a user