Return NotFound error when no torrents or quality matches found instead of silent empty response
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/claude-agent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -245,8 +245,9 @@ func (w *monitorWorkflow) run(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(parsed) == 0 {
|
if len(parsed) == 0 {
|
||||||
w.publisher.PublishStatus(ctx, pb.MonitorStep_MONITOR_STEP_COMPLETE, "No parseable results found", nil)
|
err := fmt.Errorf("no torrents found for %s", album.GetTitle())
|
||||||
return w.publisher.PublishResult(ctx, w.service.buildMonitorAlbumResponse(ctx, album, dbAlbum, nil))
|
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 {
|
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)
|
filtered := filterByQuality(parsed, w.req.Quality)
|
||||||
if len(filtered) == 0 {
|
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")
|
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)
|
w.publisher.PublishError(ctx, pb.MonitorStep_MONITOR_STEP_FILTERING_QUALITY, err, false)
|
||||||
return w.publisher.PublishResult(ctx, w.service.buildMonitorAlbumResponse(ctx, album, dbAlbum, nil))
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var best parsedItem
|
var best parsedItem
|
||||||
|
|||||||
+7
-2
@@ -13,6 +13,8 @@ import (
|
|||||||
"github.com/riverqueue/river"
|
"github.com/riverqueue/river"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
metadataPb "homelab.lan/music-agregator/gen/metadata/v1"
|
metadataPb "homelab.lan/music-agregator/gen/metadata/v1"
|
||||||
pb "homelab.lan/music-agregator/gen/music_agregator/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)
|
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())
|
filtered := filterByQuality(parsed, req.GetQuality())
|
||||||
if len(filtered) == 0 {
|
if len(filtered) == 0 {
|
||||||
log.Warn().Str("album", album.GetTitle()).Str("quality", req.GetQuality().String()).Msg("no releases match quality filter")
|
return nil, status.Errorf(codes.NotFound, "no releases match quality filter for %s", album.GetTitle())
|
||||||
return service.buildMonitorAlbumResponse(ctx, album, dbAlbum, nil), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
best := selectBestRelease(filtered)
|
best := selectBestRelease(filtered)
|
||||||
|
|||||||
@@ -507,24 +507,15 @@ func TestMonitorAlbumStream_AutomaticNoResults(t *testing.T) {
|
|||||||
|
|
||||||
messages := collectAllMessages(t, stream, 0)
|
messages := collectAllMessages(t, stream, 0)
|
||||||
|
|
||||||
assertContainsStep(t, messages, pb.MonitorStep_MONITOR_STEP_COMPLETE)
|
var hasError bool
|
||||||
|
|
||||||
var result *pb.MonitorAlbumResponse
|
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
if r := msg.GetResult(); r != nil {
|
if errUpdate := msg.GetError(); errUpdate != nil {
|
||||||
result = r
|
hasError = true
|
||||||
|
assert.Contains(t, errUpdate.Message, "no torrents found")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require.NotNil(t, result)
|
assert.True(t, hasError, "expected error event for no results")
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonitorAlbumStream_AutomaticAllSeedersZero(t *testing.T) {
|
func TestMonitorAlbumStream_AutomaticAllSeedersZero(t *testing.T) {
|
||||||
@@ -553,16 +544,15 @@ func TestMonitorAlbumStream_AutomaticAllSeedersZero(t *testing.T) {
|
|||||||
|
|
||||||
messages := collectAllMessages(t, stream, 0)
|
messages := collectAllMessages(t, stream, 0)
|
||||||
|
|
||||||
var result *pb.MonitorAlbumResponse
|
var hasError bool
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
if r := msg.GetResult(); r != nil {
|
if errUpdate := msg.GetError(); errUpdate != nil {
|
||||||
result = r
|
hasError = true
|
||||||
|
assert.Contains(t, errUpdate.Message, "no torrents found")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require.NotNil(t, result)
|
assert.True(t, hasError, "expected error event for zero seeders")
|
||||||
require.NotNil(t, result.Album)
|
|
||||||
assert.Nil(t, result.Release)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonitorAlbumStream_AutomaticAllMagnetsFail(t *testing.T) {
|
func TestMonitorAlbumStream_AutomaticAllMagnetsFail(t *testing.T) {
|
||||||
@@ -594,16 +584,14 @@ func TestMonitorAlbumStream_AutomaticAllMagnetsFail(t *testing.T) {
|
|||||||
|
|
||||||
messages := collectAllMessages(t, stream, 0)
|
messages := collectAllMessages(t, stream, 0)
|
||||||
|
|
||||||
var result *pb.MonitorAlbumResponse
|
var hasError bool
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
if r := msg.GetResult(); r != nil {
|
if errUpdate := msg.GetError(); errUpdate != nil {
|
||||||
result = r
|
hasError = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require.NotNil(t, result)
|
assert.True(t, hasError, "expected error event for all magnets failing")
|
||||||
require.NotNil(t, result.Album)
|
|
||||||
assert.Nil(t, result.Release)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonitorAlbumStream_AutomaticNoQualityMatch(t *testing.T) {
|
func TestMonitorAlbumStream_AutomaticNoQualityMatch(t *testing.T) {
|
||||||
@@ -635,18 +623,15 @@ func TestMonitorAlbumStream_AutomaticNoQualityMatch(t *testing.T) {
|
|||||||
|
|
||||||
messages := collectAllMessages(t, stream, 0)
|
messages := collectAllMessages(t, stream, 0)
|
||||||
|
|
||||||
assertContainsStep(t, messages, pb.MonitorStep_MONITOR_STEP_FILTERING_QUALITY)
|
var hasError bool
|
||||||
|
|
||||||
var result *pb.MonitorAlbumResponse
|
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
if r := msg.GetResult(); r != nil {
|
if errUpdate := msg.GetError(); errUpdate != nil {
|
||||||
result = r
|
hasError = true
|
||||||
|
assert.Contains(t, errUpdate.Message, "no releases match quality filter")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require.NotNil(t, result)
|
assert.True(t, hasError, "expected error event for no quality match")
|
||||||
require.NotNil(t, result.Album)
|
|
||||||
assert.Nil(t, result.Release)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonitorAlbumStream_AutomaticQBitDown(t *testing.T) {
|
func TestMonitorAlbumStream_AutomaticQBitDown(t *testing.T) {
|
||||||
|
|||||||
@@ -320,24 +320,15 @@ func TestMonitorAlbum_IndexerNoResults(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
_, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
||||||
AlbumId: "test-album-ext-id",
|
AlbumId: "test-album-ext-id",
|
||||||
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
||||||
})
|
})
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.Error(t, err)
|
||||||
require.NotNil(t, resp.Album)
|
st, ok := status.FromError(err)
|
||||||
require.NotNil(t, resp.Artist)
|
require.True(t, ok)
|
||||||
assert.Nil(t, resp.Release)
|
assert.Equal(t, codes.NotFound, st.Code())
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonitorAlbum_AllSeedersZero(t *testing.T) {
|
func TestMonitorAlbum_AllSeedersZero(t *testing.T) {
|
||||||
@@ -359,15 +350,15 @@ func TestMonitorAlbum_AllSeedersZero(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
_, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
||||||
AlbumId: "test-album-ext-id",
|
AlbumId: "test-album-ext-id",
|
||||||
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
||||||
})
|
})
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.Error(t, err)
|
||||||
require.NotNil(t, resp.Album)
|
st, ok := status.FromError(err)
|
||||||
require.NotNil(t, resp.Artist)
|
require.True(t, ok)
|
||||||
assert.Nil(t, resp.Release)
|
assert.Equal(t, codes.NotFound, st.Code())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonitorAlbum_AllMagnetsFail(t *testing.T) {
|
func TestMonitorAlbum_AllMagnetsFail(t *testing.T) {
|
||||||
@@ -392,15 +383,15 @@ func TestMonitorAlbum_AllMagnetsFail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
_, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
||||||
AlbumId: "test-album-ext-id",
|
AlbumId: "test-album-ext-id",
|
||||||
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
||||||
})
|
})
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.Error(t, err)
|
||||||
require.NotNil(t, resp.Album)
|
st, ok := status.FromError(err)
|
||||||
require.NotNil(t, resp.Artist)
|
require.True(t, ok)
|
||||||
assert.Nil(t, resp.Release)
|
assert.Equal(t, codes.NotFound, st.Code())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonitorAlbum_NoQualityMatch(t *testing.T) {
|
func TestMonitorAlbum_NoQualityMatch(t *testing.T) {
|
||||||
@@ -425,15 +416,15 @@ func TestMonitorAlbum_NoQualityMatch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
_, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
||||||
AlbumId: "test-album-ext-id",
|
AlbumId: "test-album-ext-id",
|
||||||
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
||||||
})
|
})
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.Error(t, err)
|
||||||
require.NotNil(t, resp.Album)
|
st, ok := status.FromError(err)
|
||||||
require.NotNil(t, resp.Artist)
|
require.True(t, ok)
|
||||||
assert.Nil(t, resp.Release)
|
assert.Equal(t, codes.NotFound, st.Code())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMonitorAlbum_QBitDown(t *testing.T) {
|
func TestMonitorAlbum_QBitDown(t *testing.T) {
|
||||||
@@ -1149,14 +1140,15 @@ func TestMonitorAlbum_SearchRetryAllExhausted(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
resp, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
_, err := suite.client.MonitorAlbum(ctx, &pb.MonitorAlbumRequest{
|
||||||
AlbumId: "test-album-ext-id",
|
AlbumId: "test-album-ext-id",
|
||||||
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
Quality: pb.QualityType_QUALITY_LOSSLESS,
|
||||||
})
|
})
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.Error(t, err)
|
||||||
require.NotNil(t, resp.Album)
|
st, ok := status.FromError(err)
|
||||||
assert.Nil(t, resp.Release)
|
require.True(t, ok)
|
||||||
|
assert.Equal(t, codes.NotFound, st.Code())
|
||||||
assert.Equal(t, 2, queryCount)
|
assert.Equal(t, 2, queryCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user