diff --git a/core/settings.go b/core/settings.go index e29f2bd3..ceb131d2 100644 --- a/core/settings.go +++ b/core/settings.go @@ -255,7 +255,7 @@ type S3Config struct { // Validate makes S3Config validatable by implementing [validation.Validatable] interface. func (c S3Config) Validate() error { return validation.ValidateStruct(&c, - validation.Field(&c.Endpoint, is.Host, validation.When(c.Enabled, validation.Required)), + validation.Field(&c.Endpoint, is.URL, validation.When(c.Enabled, validation.Required)), validation.Field(&c.Bucket, validation.When(c.Enabled, validation.Required)), validation.Field(&c.Region, validation.When(c.Enabled, validation.Required)), validation.Field(&c.AccessKey, validation.When(c.Enabled, validation.Required)), diff --git a/core/settings_test.go b/core/settings_test.go index a5c25a49..a86d43d2 100644 --- a/core/settings_test.go +++ b/core/settings_test.go @@ -315,7 +315,19 @@ func TestS3ConfigValidate(t *testing.T) { }, true, }, - // valid data + // valid data (url endpoint) + { + core.S3Config{ + Enabled: true, + Endpoint: "https://localhost:8090", + Bucket: "test", + Region: "test", + AccessKey: "test", + Secret: "test", + }, + false, + }, + // valid data (hostname endpoint) { core.S3Config{ Enabled: true, diff --git a/forms/record_upsert.go b/forms/record_upsert.go index ba21e94c..eaa1d949 100644 --- a/forms/record_upsert.go +++ b/forms/record_upsert.go @@ -3,6 +3,7 @@ package forms import ( "encoding/json" "errors" + "fmt" "net/http" "regexp" "strconv" @@ -316,17 +317,22 @@ func (form *RecordUpsert) processFilesToUpload() error { } defer fs.Close() + var uploadErrors []error for i := len(form.filesToUpload) - 1; i >= 0; i-- { file := form.filesToUpload[i] path := form.record.BaseFilesPath() + "/" + file.Name() if err := fs.Upload(file.Bytes(), path); err == nil { + // remove the uploaded file from the list form.filesToUpload = append(form.filesToUpload[:i], form.filesToUpload[i+1:]...) + } else { + // store the upload error + uploadErrors = append(uploadErrors, fmt.Errorf("File %d: %v", i, err)) } } - if len(form.filesToUpload) > 0 { - return errors.New("Failed to upload all files.") + if len(uploadErrors) > 0 { + return fmt.Errorf("Failed to upload all files: %v", uploadErrors) } return nil @@ -347,20 +353,25 @@ func (form *RecordUpsert) processFilesToDelete() error { } defer fs.Close() + var deleteErrors []error for i := len(form.filesToDelete) - 1; i >= 0; i-- { filename := form.filesToDelete[i] path := form.record.BaseFilesPath() + "/" + filename if err := fs.Delete(path); err == nil { + // remove the deleted file from the list form.filesToDelete = append(form.filesToDelete[:i], form.filesToDelete[i+1:]...) + } else { + // store the delete error + deleteErrors = append(deleteErrors, fmt.Errorf("File %d: %v", i, err)) } // try to delete the related file thumbs (if any) fs.DeletePrefix(form.record.BaseFilesPath() + "/thumbs_" + filename + "/") } - if len(form.filesToDelete) > 0 { - return errors.New("Failed to delete all files.") + if len(deleteErrors) > 0 { + return fmt.Errorf("Failed to delete all files: %v", deleteErrors) } return nil