mirror of
https://github.com/direct-img/direct-img.link.git
synced 2026-03-17 03:01:01 +00:00
Feat: Add detailed fetch failure logging to ntfy
This commit is contained in:
@@ -142,19 +142,36 @@ export async function onRequest(context) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const imageUrls = await braveImageSearch(query, env.BRAVE_API_KEY);
|
const imageUrls = await braveImageSearch(query, env.BRAVE_API_KEY);
|
||||||
if (!imageUrls || imageUrls.length === 0) return await fail("Search Failed", `No results for: ${query}`, "question", 3);
|
if (!imageUrls || imageUrls.length === 0) return await fail("Search Failed", `Brave API returned no results for: ${query}`, "question", 3);
|
||||||
|
|
||||||
const GLOBAL_DEADLINE = Date.now() + 20000;
|
const GLOBAL_DEADLINE = Date.now() + 20000;
|
||||||
let imgResult = null;
|
let imgResult = null;
|
||||||
|
const failReasons = [];
|
||||||
|
|
||||||
for (const imgUrl of imageUrls) {
|
for (const imgUrl of imageUrls) {
|
||||||
const remaining = GLOBAL_DEADLINE - Date.now();
|
const remaining = GLOBAL_DEADLINE - Date.now();
|
||||||
if (remaining <= 500) break;
|
if (remaining <= 500) {
|
||||||
imgResult = await fetchImage(imgUrl, Math.min(remaining, 5000));
|
failReasons.push("Global timeout reached");
|
||||||
if (imgResult) break;
|
break;
|
||||||
|
}
|
||||||
|
const res = await fetchImage(imgUrl, Math.min(remaining, 5000));
|
||||||
|
if (res.success) {
|
||||||
|
imgResult = res;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const host = new URL(imgUrl).hostname.replace(/^www\./, '');
|
||||||
|
failReasons.push(`${host}=${res.reason}`);
|
||||||
|
} catch {
|
||||||
|
failReasons.push(`invalid_url=${res.reason}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!imgResult) return await fail("Fetch Error (502)", `All sources failed for: ${query}`, "boom,x", 4);
|
if (!imgResult) {
|
||||||
|
const reasonStr = failReasons.slice(0, 6).join(", ") + (failReasons.length > 6 ? ", ..." : "");
|
||||||
|
return await fail("Fetch Error (502)", `All sources failed for: ${query}\nReasons: ${reasonStr}`, "boom,x", 4);
|
||||||
|
}
|
||||||
|
|
||||||
const { buffer: imgBuffer, contentType: finalContentType } = imgResult;
|
const { buffer: imgBuffer, contentType: finalContentType } = imgResult;
|
||||||
await env.R2_IMAGES.put(r2Key, imgBuffer, { httpMetadata: { contentType: finalContentType } });
|
await env.R2_IMAGES.put(r2Key, imgBuffer, { httpMetadata: { contentType: finalContentType } });
|
||||||
@@ -201,13 +218,21 @@ async function fetchImage(imageUrl, timeoutMs = 5000) {
|
|||||||
headers: { "User-Agent": "Mozilla/5.0", "Accept": "image/avif,image/webp,image/*,*/*;q=0.8" },
|
headers: { "User-Agent": "Mozilla/5.0", "Accept": "image/avif,image/webp,image/*,*/*;q=0.8" },
|
||||||
redirect: "follow", signal: AbortSignal.timeout(timeoutMs), cf: { cacheTtl: 0 }
|
redirect: "follow", signal: AbortSignal.timeout(timeoutMs), cf: { cacheTtl: 0 }
|
||||||
});
|
});
|
||||||
if (!res.ok || !res.headers.get("content-type")?.startsWith("image/")) return null;
|
if (!res.ok) return { success: false, reason: `HTTP ${res.status}` };
|
||||||
|
|
||||||
|
const ct = res.headers.get("content-type") || "";
|
||||||
|
if (!ct.startsWith("image/")) return { success: false, reason: `Bad CT: ${ct.split(';')[0]}` };
|
||||||
|
|
||||||
const size = res.headers.get("content-length");
|
const size = res.headers.get("content-length");
|
||||||
if (size && parseInt(size) > 10485760) return null;
|
if (size && parseInt(size) > 10485760) return { success: false, reason: `Header >10MB` };
|
||||||
|
|
||||||
const buffer = await res.arrayBuffer();
|
const buffer = await res.arrayBuffer();
|
||||||
if (buffer.byteLength > 10485760) return null;
|
if (buffer.byteLength > 10485760) return { success: false, reason: `Buffer >10MB` };
|
||||||
return { buffer, contentType: res.headers.get("content-type") };
|
|
||||||
} catch { return null; }
|
return { success: true, buffer, contentType: ct };
|
||||||
|
} catch (err) {
|
||||||
|
return { success: false, reason: err.name === 'TimeoutError' ? 'Timeout' : err.message };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function imageHeaders(contentType, maxAgeMs) {
|
function imageHeaders(contentType, maxAgeMs) {
|
||||||
|
|||||||
Reference in New Issue
Block a user