From dac35c77721c97f093a44d98164b38534452de9f Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 2 Apr 2026 21:42:33 +0300 Subject: task 00m/00n/00b: remove dead stub, add interface assertions, fix HTTP timeout - Remove dead DownloadImage stub from image/search.go (always returned nil, real implementation lives in Downloader.DownloadImage in download.go) - Add compile-time interface assertions for OpenAIProvider, ProviderWithFallback, and OpenAIClient to catch interface drift at compile time - Replace http.DefaultClient (no timeout) with a shared imageHTTPClient (60s timeout) in both OpenAIClient and NanoBananaClient Download methods; prevents goroutine hangs on slow/unresponsive image servers Co-Authored-By: Claude Sonnet 4.6 --- internal/image/nanobanana.go | 2 +- internal/image/openai.go | 10 +++++++++- internal/image/search.go | 6 ------ 3 files changed, 10 insertions(+), 8 deletions(-) (limited to 'internal/image') diff --git a/internal/image/nanobanana.go b/internal/image/nanobanana.go index 93afe06..a35e4cf 100644 --- a/internal/image/nanobanana.go +++ b/internal/image/nanobanana.go @@ -157,7 +157,7 @@ func (c *NanoBananaClient) Download(ctx context.Context, url string) (io.ReadClo return nil, err } - resp, err := http.DefaultClient.Do(req) + resp, err := imageHTTPClient.Do(req) if err != nil { return nil, err } diff --git a/internal/image/openai.go b/internal/image/openai.go index e322d32..8edb182 100644 --- a/internal/image/openai.go +++ b/internal/image/openai.go @@ -13,6 +13,14 @@ import ( "github.com/sashabaranov/go-openai" ) +// Compile-time check that OpenAIClient implements the ImageSearcher interface. +var _ ImageSearcher = (*OpenAIClient)(nil) + +// imageHTTPClient is a shared HTTP client with a generous timeout for image +// downloads. http.DefaultClient has no timeout, which can block goroutines +// indefinitely on slow or unresponsive servers. +var imageHTTPClient = &http.Client{Timeout: 60 * time.Second} + // OpenAIClient implements ImageSearcher for OpenAI DALL-E image generation type OpenAIClient struct { client *openai.Client @@ -190,7 +198,7 @@ func (c *OpenAIClient) Download(ctx context.Context, url string) (io.ReadCloser, return nil, err } - resp, err := http.DefaultClient.Do(req) + resp, err := imageHTTPClient.Do(req) if err != nil { return nil, err } diff --git a/internal/image/search.go b/internal/image/search.go index 53004c1..80274eb 100644 --- a/internal/image/search.go +++ b/internal/image/search.go @@ -81,9 +81,3 @@ func (e *RateLimitError) Error() string { return e.Provider + ": rate limit exceeded" } -// DownloadImage is a utility function to download an image to a file -func DownloadImage(ctx context.Context, searcher ImageSearcher, url string, outputPath string) error { - // Implementation will be in a separate download.go file - // This is just the interface definition - return nil -} -- cgit v1.2.3