diff --git a/internal/media/service.go b/internal/media/service.go index ed890cc7..53a16f70 100644 --- a/internal/media/service.go +++ b/internal/media/service.go @@ -148,7 +148,7 @@ func (s *Service) IngestContainerFile(ctx context.Context, botID, containerPath } opener, ok := s.provider.(storage.ContainerFileOpener) if !ok { - return Asset{}, errors.New("provider does not support container file reading") + return Asset{}, storage.ErrContainerFileNotSupported } f, err := opener.OpenContainerFile(ctx, botID, containerPath) if err != nil { diff --git a/internal/storage/providers/fallback/provider.go b/internal/storage/providers/fallback/provider.go index 51818151..3c450a6a 100644 --- a/internal/storage/providers/fallback/provider.go +++ b/internal/storage/providers/fallback/provider.go @@ -10,6 +10,8 @@ import ( "github.com/memohai/memoh/internal/storage" ) +var _ storage.ContainerFileOpener = (*Provider)(nil) + // Provider delegates to primary and falls back to secondary on write errors. type Provider struct { primary storage.Provider @@ -79,3 +81,18 @@ func tryListPrefix(ctx context.Context, p storage.Provider, prefix string) ([]st } return nil, nil } + +// OpenContainerFile delegates to whichever inner provider implements +// storage.ContainerFileOpener, trying the primary first. +func (p *Provider) OpenContainerFile(ctx context.Context, botID, containerPath string) (io.ReadCloser, error) { + if opener, ok := p.primary.(storage.ContainerFileOpener); ok { + rc, err := opener.OpenContainerFile(ctx, botID, containerPath) + if err == nil { + return rc, nil + } + } + if opener, ok := p.secondary.(storage.ContainerFileOpener); ok { + return opener.OpenContainerFile(ctx, botID, containerPath) + } + return nil, storage.ErrContainerFileNotSupported +} diff --git a/internal/storage/storage.go b/internal/storage/storage.go index d0cc3aa5..1caa1bd3 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -3,9 +3,14 @@ package storage import ( "context" + "errors" "io" ) +// ErrContainerFileNotSupported is returned when no underlying provider +// implements ContainerFileOpener. +var ErrContainerFileNotSupported = errors.New("provider does not support container file reading") + // Provider abstracts object storage operations. type Provider interface { // Put writes data to storage under the given key.