diff --git a/CHANGELOG.md b/CHANGELOG.md index 112265c2..e0ffe051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ - Fixed typo in `Record.WithUnkownData()` -> `Record.WithUnknownData()`. +## v0.14.5 + +- Added checks for `nil` hooks in `forms.RecordUpsert` when used with custom `Dao` ([#2277](https://github.com/pocketbase/pocketbase/issues/2277)). + + ## v0.14.4 - Fixed concurrent map write pannic on `list.ExistInSliceWithRegex()` cache ([#2272](https://github.com/pocketbase/pocketbase/issues/2272)). diff --git a/forms/record_upsert.go b/forms/record_upsert.go index eb04e137..daf38d29 100644 --- a/forms/record_upsert.go +++ b/forms/record_upsert.go @@ -749,8 +749,10 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc[*models.Record] // but BEFORE the actual record db persistence // --- dao.BeforeCreateFunc = func(eventDao *daos.Dao, m models.Model) error { - if err := form.dao.BeforeCreateFunc(eventDao, m); err != nil { - return err + if form.dao.BeforeCreateFunc != nil { + if err := form.dao.BeforeCreateFunc(eventDao, m); err != nil { + return err + } } if m.GetId() == form.record.GetId() { @@ -761,8 +763,10 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc[*models.Record] } dao.BeforeUpdateFunc = func(eventDao *daos.Dao, m models.Model) error { - if err := form.dao.BeforeUpdateFunc(eventDao, m); err != nil { - return err + if form.dao.BeforeUpdateFunc != nil { + if err := form.dao.BeforeUpdateFunc(eventDao, m); err != nil { + return err + } } if m.GetId() == form.record.GetId() { diff --git a/forms/record_upsert_test.go b/forms/record_upsert_test.go index a93cc517..bd006aba 100644 --- a/forms/record_upsert_test.go +++ b/forms/record_upsert_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "errors" + "fmt" "net/http" "net/http/httptest" "os" @@ -1047,41 +1048,54 @@ func TestRecordUpsertUploadFailure(t *testing.T) { t.Fatal(err) } - // create with invalid file - { - new := models.NewRecord(collection) - new.Id = "123456789012341" - - form := forms.NewRecordUpsert(app, new) - form.LoadData(map[string]any{"title": "new_test"}) - form.AddFiles("files", &filesystem.File{Reader: &filesystem.PathReader{Path: "/tmp/__missing__"}}) - - if err := form.Submit(); err == nil { - t.Fatal("Expected error, got nil") - } - - if r, err := app.Dao().FindRecordById(collection.Id, new.Id); err == nil { - t.Fatalf("Expected the inserted record to be deleted, found \n%v", r.PublicExport()) - } + testDaos := []*daos.Dao{ + app.Dao(), // with hooks + daos.New(app.Dao().DB()), // without hooks } - // update with invalid file - { - record, err := app.Dao().FindRecordById(collection.Id, "1tmknxy2868d869") - if err != nil { - t.Fatal(err) + for i, dao := range testDaos { + // create with invalid file + { + prefix := fmt.Sprintf("%d-create", i) + + new := models.NewRecord(collection) + new.Id = "123456789012341" + + form := forms.NewRecordUpsert(app, new) + form.SetDao(dao) + form.LoadData(map[string]any{"title": "new_test"}) + form.AddFiles("files", &filesystem.File{Reader: &filesystem.PathReader{Path: "/tmp/__missing__"}}) + + if err := form.Submit(); err == nil { + t.Fatalf("[%s] Expected error, got nil", prefix) + } + + if r, err := app.Dao().FindRecordById(collection.Id, new.Id); err == nil { + t.Fatalf("[%s] Expected the inserted record to be deleted, found \n%v", prefix, r.PublicExport()) + } } - form := forms.NewRecordUpsert(app, record) - form.LoadData(map[string]any{"title": "update_test"}) - form.AddFiles("files", &filesystem.File{Reader: &filesystem.PathReader{Path: "/tmp/__missing__"}}) + // update with invalid file + { + prefix := fmt.Sprintf("%d-update", i) - if err := form.Submit(); err == nil { - t.Fatal("Expected error, got nil") - } + record, err := app.Dao().FindRecordById(collection.Id, "1tmknxy2868d869") + if err != nil { + t.Fatal(err) + } - if r, _ := app.Dao().FindRecordById(collection.Id, record.Id); r == nil || r.GetString("title") == "update_test" { - t.Fatalf("Expected the record changes to be reverted, got \n%v", r.PublicExport()) + form := forms.NewRecordUpsert(app, record) + form.SetDao(dao) + form.LoadData(map[string]any{"title": "update_test"}) + form.AddFiles("files", &filesystem.File{Reader: &filesystem.PathReader{Path: "/tmp/__missing__"}}) + + if err := form.Submit(); err == nil { + t.Fatalf("[%s] Expected error, got nil", prefix) + } + + if r, _ := app.Dao().FindRecordById(collection.Id, record.Id); r == nil || r.GetString("title") == "update_test" { + t.Fatalf("[%s] Expected the record changes to be reverted, got \n%v", prefix, r.PublicExport()) + } } } }