mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-03 03:12:31 +00:00
fix(upload): attach CORS guidance to direct upload failures
A new user's top first-upload failure is a missing R2 CORS policy (browser PUT/POST blocked) -- and object-scoped R2 tokens often cannot auto-set CORS. The connection test already surfaces buildCorsGuidance on the opaque "Failed to fetch", but a user who skips the test and uploads directly got a bare "Upload failed: Failed to fetch". The upload error handler now detects the browser CORS/network rejection (isLikelyCorsError -- Chrome "Failed to fetch", Firefox "NetworkError", Safari "Load failed") and appends the same actionable guidance. Updated the R2 follow-up TODO (credential audit done; CORS reviewed). Test: tests/services/r2-cors-error-classifier.test.mjs. Full suite green. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
200e5cec80
commit
7f5dcd7e50
3 files changed
+79
-15
No files matched your search
@@ -103,6 +103,25 @@ function buildCorsGuidance({ accountId } = {}) {
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
/**
|
||||
* A browser CORS preflight/rejection surfaces as an opaque network error
|
||||
* ("Failed to fetch" / "NetworkError" / Safari's "Load failed") with no HTTP
|
||||
* status — indistinguishable from a real network drop. We treat these as
|
||||
* likely-CORS so the upload path can attach actionable guidance instead of a
|
||||
* bare "Failed to fetch".
|
||||
*/
|
||||
export function isLikelyCorsError(err) {
|
||||
const message = (
|
||||
(err && (err.message || err.toString && err.toString())) ||
|
||||
""
|
||||
).toLowerCase();
|
||||
return (
|
||||
message.includes("failed to fetch") ||
|
||||
message.includes("networkerror") ||
|
||||
message.includes("load failed")
|
||||
);
|
||||
}
|
||||
|
||||
function createDefaultSettings() {
|
||||
return {
|
||||
accountId: "",
|
||||
@@ -1251,10 +1270,16 @@ export class R2Service {
|
||||
return publishOutcome;
|
||||
} catch (err) {
|
||||
userLogger.error("Cloudflare upload failed:", err);
|
||||
this.setCloudflareUploadStatus(
|
||||
err?.message ? `Upload failed: ${err.message}` : "Upload failed.",
|
||||
"error"
|
||||
);
|
||||
let message = err?.message
|
||||
? `Upload failed: ${err.message}`
|
||||
: "Upload failed.";
|
||||
// A CORS rejection during the browser PUT/POST looks like an opaque
|
||||
// "Failed to fetch" — attach actionable guidance so users who skipped the
|
||||
// connection test still know what to fix (the #1 first-upload failure).
|
||||
if (isLikelyCorsError(err)) {
|
||||
message += ` ${buildCorsGuidance({ accountId })}`;
|
||||
}
|
||||
this.setCloudflareUploadStatus(message, "error");
|
||||
return false;
|
||||
} finally {
|
||||
this.setCloudflareUploading(false);
|
||||
|
||||
Reference in new issue
Block a user