From ebcbcd56949ed1de148a4e995819f3eeefc917c3 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Thu, 13 Nov 2025 12:52:17 +0400 Subject: [PATCH 1/2] return 404 for piece retrievals correctly --- lib/cachedreader/cachedreader.go | 25 +++++++++++++++++++++++-- market/retrieval/piecehandler.go | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/cachedreader/cachedreader.go b/lib/cachedreader/cachedreader.go index 59f6cf132..0d8ea7966 100644 --- a/lib/cachedreader/cachedreader.go +++ b/lib/cachedreader/cachedreader.go @@ -4,6 +4,7 @@ import ( "context" "errors" "io" + "net/http" "sync" "time" @@ -23,6 +24,7 @@ import ( ) var ErrNoDeal = errors.New("no deals found") +var ErrNotFound = errors.New("piece not found") var log = logging.Logger("cached-reader") @@ -222,7 +224,7 @@ func (cpr *CachedPieceReader) getPieceReaderFromPiecePark(ctx context.Context, p } if len(pieceData) == 0 { - return nil, 0, xerrors.Errorf("failed to find piece in parked_pieces for piece cid %s", pieceCid.String()) + return nil, 0, xerrors.Errorf("failed to find piece in parked_pieces for piece cid %s: %w", pieceCid.String(), ErrNoDeal) } reader, err := cpr.pieceParkReader.ReadPiece(ctx, storiface.PieceNumber(pieceData[0].ID), pieceData[0].PieceRawSize, pieceCid) @@ -283,10 +285,16 @@ func (cpr *CachedPieceReader) GetSharedPieceReader(ctx context.Context, pieceCid readerCtx, readerCtxCancel := context.WithCancel(context.Background()) defer close(r.ready) + retCode := http.StatusNotFound + reader, size, err := cpr.getPieceReaderFromSector(readerCtx, pieceCid) if err != nil { log.Infow("failed to get piece reader from sector", "piececid", pieceCid, "err", err) + if !errors.Is(err, ErrNoDeal) { + retCode = http.StatusInternalServerError + } + serr := err // Try getPieceReaderFromPiecePark @@ -294,7 +302,20 @@ func (cpr *CachedPieceReader) GetSharedPieceReader(ctx context.Context, pieceCid if err != nil { log.Errorw("failed to get piece reader from piece park", "piececid", pieceCid, "err", err) - finalErr := xerrors.Errorf("failed to get piece reader from sector or piece park: %w, %w", err, serr) + // If we already hit any error except ErrNoDeal then we should surface that one even if here we get a 404. + // If previous error was 404 but here it is anything but 404 then we should surface that + // 404 should only be surfaced if we have 404 from both errors + if retCode == http.StatusNotFound && !errors.Is(err, ErrNoDeal) { + retCode = http.StatusInternalServerError + } + + var finalErr error + + if retCode == http.StatusNotFound { + finalErr = xerrors.Errorf("failed to get piece reader from sector or piece park: %w, %w, %w", err, serr, ErrNotFound) + } else { + finalErr = xerrors.Errorf("failed to get piece reader from sector or piece park: %w, %w", err, serr) + } // Record error metric _ = stats.RecordWithTags(context.Background(), []tag.Mutator{ diff --git a/market/retrieval/piecehandler.go b/market/retrieval/piecehandler.go index 33ce0c57f..38efb9608 100644 --- a/market/retrieval/piecehandler.go +++ b/market/retrieval/piecehandler.go @@ -61,7 +61,7 @@ func (rp *Provider) handleByPieceCid(w http.ResponseWriter, r *http.Request) { reader, size, err := rp.cpr.GetSharedPieceReader(ctx, pieceCid) if err != nil { log.Errorf("server error getting content for piece CID %s: %s", pieceCid, err) - if errors.Is(err, cachedreader.ErrNoDeal) { + if errors.Is(err, cachedreader.ErrNotFound) { w.WriteHeader(http.StatusNotFound) stats.Record(ctx, remoteblockstore.HttpPieceByCid404ResponseCount.M(1)) return From da75ff03c850b578414fbcce704ae218d055a29a Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 15 Nov 2025 17:02:20 -0300 Subject: [PATCH 2/2] fix multiple wrapped errors with xerrors.Errorf Signed-off-by: Jakub Sztandera --- lib/cachedreader/cachedreader.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/cachedreader/cachedreader.go b/lib/cachedreader/cachedreader.go index 0d8ea7966..13d5ff5c7 100644 --- a/lib/cachedreader/cachedreader.go +++ b/lib/cachedreader/cachedreader.go @@ -3,6 +3,7 @@ package cachedreader import ( "context" "errors" + "fmt" "io" "net/http" "sync" @@ -312,9 +313,9 @@ func (cpr *CachedPieceReader) GetSharedPieceReader(ctx context.Context, pieceCid var finalErr error if retCode == http.StatusNotFound { - finalErr = xerrors.Errorf("failed to get piece reader from sector or piece park: %w, %w, %w", err, serr, ErrNotFound) + finalErr = fmt.Errorf("failed to get piece reader from sector or piece park: %w, %w, %w", err, serr, ErrNotFound) } else { - finalErr = xerrors.Errorf("failed to get piece reader from sector or piece park: %w, %w", err, serr) + finalErr = fmt.Errorf("failed to get piece reader from sector or piece park: %w, %w", err, serr) } // Record error metric