diff --git a/internal/monitor_workflow.go b/internal/monitor_workflow.go index d7af730..462213d 100644 --- a/internal/monitor_workflow.go +++ b/internal/monitor_workflow.go @@ -245,8 +245,9 @@ func (w *monitorWorkflow) run(ctx context.Context) error { } if len(parsed) == 0 { - w.publisher.PublishStatus(ctx, pb.MonitorStep_MONITOR_STEP_COMPLETE, "No parseable results found", nil) - return w.publisher.PublishResult(ctx, w.service.buildMonitorAlbumResponse(ctx, album, dbAlbum, nil)) + err := fmt.Errorf("no torrents found for %s", album.GetTitle()) + w.publisher.PublishError(ctx, pb.MonitorStep_MONITOR_STEP_PARSING_RESULTS, err, false) + return err } if w.mode == pb.InteractionMode_INTERACTION_MODE_MANUAL && len(parsed) > 1 { @@ -305,9 +306,10 @@ func (w *monitorWorkflow) run(ctx context.Context) error { filtered := filterByQuality(parsed, w.req.Quality) if len(filtered) == 0 { + err := fmt.Errorf("no releases match quality filter for %s", album.GetTitle()) log.Warn().Str("album", album.GetTitle()).Str("quality", w.req.Quality.String()).Msg("no releases match quality filter") - w.publisher.PublishStatus(ctx, pb.MonitorStep_MONITOR_STEP_COMPLETE, "No releases match quality filter", nil) - return w.publisher.PublishResult(ctx, w.service.buildMonitorAlbumResponse(ctx, album, dbAlbum, nil)) + w.publisher.PublishError(ctx, pb.MonitorStep_MONITOR_STEP_FILTERING_QUALITY, err, false) + return err } var best parsedItem diff --git a/internal/service.go b/internal/service.go index 198ffcc..bb2723e 100644 --- a/internal/service.go +++ b/internal/service.go @@ -13,6 +13,8 @@ import ( "github.com/riverqueue/river" "github.com/rs/zerolog/log" "golang.org/x/sync/errgroup" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" metadataPb "homelab.lan/music-agregator/gen/metadata/v1" pb "homelab.lan/music-agregator/gen/music_agregator/v1" @@ -560,10 +562,13 @@ func (service *MusicAgregatorService) MonitorAlbum(ctx context.Context, req *pb. parsed := service.parseSearchResults(searchResult, album) + if len(parsed) == 0 { + return nil, status.Errorf(codes.NotFound, "no torrents found for %s", album.GetTitle()) + } + filtered := filterByQuality(parsed, req.GetQuality()) if len(filtered) == 0 { - log.Warn().Str("album", album.GetTitle()).Str("quality", req.GetQuality().String()).Msg("no releases match quality filter") - return service.buildMonitorAlbumResponse(ctx, album, dbAlbum, nil), nil + return nil, status.Errorf(codes.NotFound, "no releases match quality filter for %s", album.GetTitle()) } best := selectBestRelease(filtered) diff --git a/test/component/monitor_album_stream_test.go b/test/component/monitor_album_stream_test.go index 2a26f00..d079184 100644 --- a/test/component/monitor_album_stream_test.go +++ b/test/component/monitor_album_stream_test.go @@ -507,24 +507,15 @@ func TestMonitorAlbumStream_AutomaticNoResults(t *testing.T) { messages := collectAllMessages(t, stream, 0) - assertContainsStep(t, messages, pb.MonitorStep_MONITOR_STEP_COMPLETE) - - var result *pb.MonitorAlbumResponse + var hasError bool for _, msg := range messages { - if r := msg.GetResult(); r != nil { - result = r + if errUpdate := msg.GetError(); errUpdate != nil { + hasError = true + assert.Contains(t, errUpdate.Message, "no torrents found") break } } - require.NotNil(t, result) - require.NotNil(t, result.Album) - assert.Nil(t, result.Release) - - ctx := context.Background() - var count int - err := suite.pool.QueryRow(ctx, "SELECT COUNT(*) FROM torrents").Scan(&count) - require.NoError(t, err) - assert.Equal(t, 0, count) + assert.True(t, hasError, "expected error event for no results") } func TestMonitorAlbumStream_AutomaticAllSeedersZero(t *testing.T) { @@ -553,16 +544,15 @@ func TestMonitorAlbumStream_AutomaticAllSeedersZero(t *testing.T) { messages := collectAllMessages(t, stream, 0) - var result *pb.MonitorAlbumResponse + var hasError bool for _, msg := range messages { - if r := msg.GetResult(); r != nil { - result = r + if errUpdate := msg.GetError(); errUpdate != nil { + hasError = true + assert.Contains(t, errUpdate.Message, "no torrents found") break } } - require.NotNil(t, result) - require.NotNil(t, result.Album) - assert.Nil(t, result.Release) + assert.True(t, hasError, "expected error event for zero seeders") } func TestMonitorAlbumStream_AutomaticAllMagnetsFail(t *testing.T) { @@ -594,16 +584,14 @@ func TestMonitorAlbumStream_AutomaticAllMagnetsFail(t *testing.T) { messages := collectAllMessages(t, stream, 0) - var result *pb.MonitorAlbumResponse + var hasError bool for _, msg := range messages { - if r := msg.GetResult(); r != nil { - result = r + if errUpdate := msg.GetError(); errUpdate != nil { + hasError = true break } } - require.NotNil(t, result) - require.NotNil(t, result.Album) - assert.Nil(t, result.Release) + assert.True(t, hasError, "expected error event for all magnets failing") } func TestMonitorAlbumStream_AutomaticNoQualityMatch(t *testing.T) { @@ -635,18 +623,15 @@ func TestMonitorAlbumStream_AutomaticNoQualityMatch(t *testing.T) { messages := collectAllMessages(t, stream, 0) - assertContainsStep(t, messages, pb.MonitorStep_MONITOR_STEP_FILTERING_QUALITY) - - var result *pb.MonitorAlbumResponse + var hasError bool for _, msg := range messages { - if r := msg.GetResult(); r != nil { - result = r + if errUpdate := msg.GetError(); errUpdate != nil { + hasError = true + assert.Contains(t, errUpdate.Message, "no releases match quality filter") break } } - require.NotNil(t, result) - require.NotNil(t, result.Album) - assert.Nil(t, result.Release) + assert.True(t, hasError, "expected error event for no quality match") } func TestMonitorAlbumStream_AutomaticQBitDown(t *testing.T) { diff --git a/test/component/monitor_album_test.go b/test/component/monitor_album_test.go index 049669b..23b4692 100644 --- a/test/component/monitor_album_test.go +++ b/test/component/monitor_album_test.go @@ -320,24 +320,15 @@ func TestMonitorAlbum_IndexerNoResults(t *testing.T) { } ctx := context.Background() - resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ + _, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ AlbumId: "test-album-ext-id", Quality: pb.QualityType_QUALITY_LOSSLESS, }) - require.NoError(t, err) - require.NotNil(t, resp.Album) - require.NotNil(t, resp.Artist) - assert.Nil(t, resp.Release) - - var count int - err = suite.pool.QueryRow(ctx, "SELECT COUNT(*) FROM torrents").Scan(&count) - require.NoError(t, err) - assert.Equal(t, 0, count) - - err = suite.pool.QueryRow(ctx, "SELECT COUNT(*) FROM downloads").Scan(&count) - require.NoError(t, err) - assert.Equal(t, 0, count) + require.Error(t, err) + st, ok := status.FromError(err) + require.True(t, ok) + assert.Equal(t, codes.NotFound, st.Code()) } func TestMonitorAlbum_AllSeedersZero(t *testing.T) { @@ -359,15 +350,15 @@ func TestMonitorAlbum_AllSeedersZero(t *testing.T) { } ctx := context.Background() - resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ + _, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ AlbumId: "test-album-ext-id", Quality: pb.QualityType_QUALITY_LOSSLESS, }) - require.NoError(t, err) - require.NotNil(t, resp.Album) - require.NotNil(t, resp.Artist) - assert.Nil(t, resp.Release) + require.Error(t, err) + st, ok := status.FromError(err) + require.True(t, ok) + assert.Equal(t, codes.NotFound, st.Code()) } func TestMonitorAlbum_AllMagnetsFail(t *testing.T) { @@ -392,15 +383,15 @@ func TestMonitorAlbum_AllMagnetsFail(t *testing.T) { } ctx := context.Background() - resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ + _, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ AlbumId: "test-album-ext-id", Quality: pb.QualityType_QUALITY_LOSSLESS, }) - require.NoError(t, err) - require.NotNil(t, resp.Album) - require.NotNil(t, resp.Artist) - assert.Nil(t, resp.Release) + require.Error(t, err) + st, ok := status.FromError(err) + require.True(t, ok) + assert.Equal(t, codes.NotFound, st.Code()) } func TestMonitorAlbum_NoQualityMatch(t *testing.T) { @@ -425,15 +416,15 @@ func TestMonitorAlbum_NoQualityMatch(t *testing.T) { } ctx := context.Background() - resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ + _, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ AlbumId: "test-album-ext-id", Quality: pb.QualityType_QUALITY_LOSSLESS, }) - require.NoError(t, err) - require.NotNil(t, resp.Album) - require.NotNil(t, resp.Artist) - assert.Nil(t, resp.Release) + require.Error(t, err) + st, ok := status.FromError(err) + require.True(t, ok) + assert.Equal(t, codes.NotFound, st.Code()) } func TestMonitorAlbum_QBitDown(t *testing.T) { @@ -1149,14 +1140,15 @@ func TestMonitorAlbum_SearchRetryAllExhausted(t *testing.T) { } ctx := context.Background() - resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ + _, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{ AlbumId: "test-album-ext-id", Quality: pb.QualityType_QUALITY_LOSSLESS, }) - require.NoError(t, err) - require.NotNil(t, resp.Album) - assert.Nil(t, resp.Release) + require.Error(t, err) + st, ok := status.FromError(err) + require.True(t, ok) + assert.Equal(t, codes.NotFound, st.Code()) assert.Equal(t, 2, queryCount) }