(ctx context.Context, app App, record *Record)
| 510 | } |
| 511 | |
| 512 | func (f *FileField) processFilesToUpload(ctx context.Context, app App, record *Record) error { |
| 513 | uploads := f.extractUploadableFiles(f.toSliceValue(record.GetRaw(f.Name))) |
| 514 | if len(uploads) == 0 { |
| 515 | return nil |
| 516 | } |
| 517 | |
| 518 | if record.Id == "" { |
| 519 | return errors.New("uploading files requires the record to have a valid nonempty id") |
| 520 | } |
| 521 | |
| 522 | fsys, err := app.NewFilesystem() |
| 523 | if err != nil { |
| 524 | return err |
| 525 | } |
| 526 | defer fsys.Close() |
| 527 | fsys.SetContext(ctx) |
| 528 | |
| 529 | var failed []error // list of upload errors |
| 530 | var succeeded []string // list of uploaded file names |
| 531 | |
| 532 | for _, upload := range uploads { |
| 533 | path := record.BaseFilesPath() + "/" + upload.Name |
| 534 | if err := fsys.UploadFile(upload, path); err == nil { |
| 535 | succeeded = append(succeeded, upload.Name) |
| 536 | } else { |
| 537 | failed = append(failed, fmt.Errorf("%q: %w", upload.Name, err)) |
| 538 | break // for now stop on the first error since we currently don't allow partial uploads |
| 539 | } |
| 540 | } |
| 541 | |
| 542 | if len(failed) > 0 { |
| 543 | // cleanup - try to delete the successfully uploaded files (if any) |
| 544 | _, cleanupErr := f.deleteFilesByNamesList(newContextIfInvalid(ctx), app, record, succeeded) |
| 545 | |
| 546 | failed = append(failed, cleanupErr) |
| 547 | |
| 548 | return fmt.Errorf("failed to upload all files: %w", errors.Join(failed...)) |
| 549 | } |
| 550 | |
| 551 | return nil |
| 552 | } |
| 553 | |
| 554 | func (f *FileField) deleteNewlyUploadedFiles(ctx context.Context, app App, record *Record) ([]string, error) { |
| 555 | uploaded, _ := record.GetRaw(uploadedFilesPrefix + f.Name).([]*filesystem.File) |
no test coverage detected