fix(doodstream): extend 3.3.29 account-poison protection to the API path
The new API upload path POSTs to the same cloudatacdn.com nodes as the web
path, so it can hit the same backend flake — a 2xx response with no filecode, or
a transient "no servers available" from /api/upload/server (now that the stale
fallback node is gone). hosters.uploadFile threw GENERIC errors for both, which
the upload-manager would treat as an account failure → mark-failed →
pre-job-swap-blocked on the next batch: the exact symptom 3.3.29 fixed for the
web path, reintroduced via the unprotected API path.
Tag both API-path analogs of the empty form as err.hosterTransient=true:
- codeless 2xx ("lieferte keine file_code-Antwort") — bytes accepted, no link.
- transient "no upload server" (shouldRetryServerLookup true: no-servers/busy/
try-again) — but NOT genuine auth failures (invalid key/unauthorized), which
stay classified as account errors.
The upload-manager checks _isHosterTransientError (flag-based) before the
account-error classifier, so both now fail the file without blacklisting the
account. Consumption side already covered by the 3.3.29 regression test. 173/173.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
a8d81cbf0d
commit
76c56cf13b
@ -378,7 +378,13 @@ async function getUploadServer(hosterName, hosterConfig, apiKey, signal) {
|
||||
}
|
||||
|
||||
if (lastMessage) {
|
||||
throw new Error(`Kein Upload-Server erhalten: ${lastMessage}`);
|
||||
const e = new Error(`Kein Upload-Server erhalten: ${lastMessage}`);
|
||||
// "no servers available" / busy / try-again is a transient hoster-side
|
||||
// condition, not an account fault — tag it so the account isn't blacklisted.
|
||||
// Genuine auth failures (invalid key / unauthorized / forbidden) make
|
||||
// shouldRetryServerLookup return false and stay classified as account errors.
|
||||
if (shouldRetryServerLookup(lastMessage)) e.hosterTransient = true;
|
||||
throw e;
|
||||
}
|
||||
throw new Error('Kein Upload-Server erhalten. API-Key pruefen.');
|
||||
}
|
||||
@ -545,9 +551,18 @@ async function uploadFile(hosterName, filePath, apiKey, onProgress, signal, thro
|
||||
const isOkishNoPayload = /^(ok|success|done|accepted)$/i.test(msg);
|
||||
if (isOkishNoPayload || !msg) {
|
||||
const snippet = JSON.stringify(payload).slice(0, 400);
|
||||
throw new Error(
|
||||
// 2xx with no filecode: the hoster accepted the upload (bytes sent, status
|
||||
// OK) but returned no usable link. For doodstream this is the API-path
|
||||
// analog of the web empty-form — the backend file-registration timing out
|
||||
// under large-file load. It's a hoster-side flake, NOT an account problem,
|
||||
// so tag it hosterTransient: the upload-manager then fails this file WITHOUT
|
||||
// blacklisting the account (same protection the web path got in 3.3.29) and
|
||||
// the account stays usable for the next retry/batch.
|
||||
const err = new Error(
|
||||
`Upload zu ${hosterName} lieferte keine file_code-Antwort (Payload: ${snippet})`
|
||||
);
|
||||
err.hosterTransient = true;
|
||||
throw err;
|
||||
}
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user