diff --git a/app/api/proxy/route.ts b/app/api/proxy/route.ts index 0867e66..4245033 100644 --- a/app/api/proxy/route.ts +++ b/app/api/proxy/route.ts @@ -26,6 +26,19 @@ export async function GET(request: NextRequest) { const response = await fetchWithRetry({ url, request, headers: requestHeaders }); + // If upstream returned an error, pass it through with CORS headers + if (!response.ok) { + const errorText = await response.text(); + return new NextResponse(errorText || `Upstream error: ${response.status}`, { + status: response.status, + statusText: response.statusText, + headers: { + 'Content-Type': response.headers.get('Content-Type') || 'text/plain', + 'Access-Control-Allow-Origin': '*', + }, + }); + } + const contentType = response.headers.get('Content-Type'); // Better M3U8 detection: check both content-type and actual content diff --git a/lib/utils/fetch-with-retry.ts b/lib/utils/fetch-with-retry.ts index 49bb3d0..b0cf12f 100644 --- a/lib/utils/fetch-with-retry.ts +++ b/lib/utils/fetch-with-retry.ts @@ -76,8 +76,16 @@ export async function fetchWithRetry({ url, request, headers = {} }: FetchWithRe } } - if (!response || !response.ok) { - throw new Error(`Failed after ${MAX_RETRIES} attempts: ${response?.status || lastError}`); + // If we got a response (even an error response like 403, 404), return it + // Only throw if we truly failed to get any response + if (!response) { + throw new Error(`Failed after ${MAX_RETRIES} attempts: ${lastError}`); + } + + // Return the response even if it's an error status (403, 404, etc.) + // The caller can check response.ok or response.status + if (!response.ok) { + console.warn(`⚠ Returning non-OK response: ${response.status} ${response.statusText}`); } return response;