INTEGRITY Dokumentace

Chyby a výjimky

Prohlédněte si chyby a výjimky Workers.

Chybové stránky generované Workers

Pokud Worker běžící v produkci narazí na chybu, která mu zabrání vrátit odpověď, klient obdrží chybovou stránku s chybovým kódem, definovaným následovně:

Kód chyby Význam
1101 Worker vyvolal výjimku JavaScriptu.
1102 Worker překročil Limit CPU času.
1103 Vlastník tohoto Workeru musí kontaktovat Cloudflare Support
1019 Worker dosáhl limit smyčky.
1021 Worker požádal o hostitele, ke kterému nemá přístup.
1022 Cloudflare se nepodařilo směrovat požadavek na Worker.
1024 Worker nemůže vytvořit subrequest na IP adresu vlastněnou Cloudflare.
1027 Worker překročil limit bezplatné úrovně denní limit požadavků.
1042 Worker se pokusil o fetch z jiného Workeru ve stejné zóně, což je možné pouze podporováno když global_fetch_strictly_public příznak kompatibility se používá.
10162 Modul má nepodporovaný Content-Type.

Další 11xx chyby obvykle značí problém přímo v běhovém prostředí Workers. Podrobnosti v stránka stavu pokud se u vás vyskytuje chyba.

Limit smyčky

Worker nemůže zavolat sám sebe ani jiný Worker více než 16krát. Aby se zabránilo nekonečným smyčkám mezi Workery, CF-EW-Via hlavičky je celé číslo udávající, kolik vyvolání ještě zbývá. Při každém vyvolání Workeru se toto číslo sníží o 1. Jakmile dosáhne nuly, 1019 se vrátí chyba.

"The script will never generate a response" errors

Některé požadavky mohou vrátit chybu 1101 s The script will never generate a response v chybové zprávě. K tomu dochází, když Workers runtime zjistí, že veškerý kód spojený s požadavkem byl proveden a v event loopu nezůstaly žádné události, ale Response nebyla vrácena.

Příčina 1: Nevyřešené Promises

Nejčastější příčinou je spoléhání na Promise, který nikdy není resolved ani rejected, přestože je potřeba k vrácení Response. Při ladění hledejte ve svém kódu nebo v kódu závislostí Promises, které blokují Response, a ujistěte se, že jsou resolved nebo rejected.

V prohlížečích a jiných JavaScript runtimech by se ekvivalentní kód zaseknul na neurčito, což vede k chybám i únikům paměti. Runtime Workers místo toho vyvolá explicitní chybu, která vám pomůže s laděním.

V následujícím příkladu závisí Response na vyřešení Promise, ke kterému nikdy nedojde. Odkomentováním resolve callback problém vyřeší.

export default {
	fetch(req) {
		let response = new Response("Example response");
		let { promise, resolve } = Promise.withResolvers();

		// If the promise is not resolved, the Workers runtime will
		// recognize this and throw an error.

		// setTimeout(resolve, 0)

		return promise.then(() => response);
	},
};

Tomu můžete zabránit vynucením no-floating-promises pravidlo eslint, který hlásí, kdy je Promise vytvořen a není řádně obsloužen.

Příčina 2: WebSocket připojení, která nejsou nikdy uzavřena

Pokud WebSocketu chybí správný kód pro ukončení připojení na straně serveru, prostředí Workers runtime vyvolá script will never generate a response chyba. V následujícím příkladu 'close' událost od klienta není správně obsloužena voláním server.close(), a dojde k vyvolání chyby. Abyste tomu předešli, zajistěte, aby se serverová strana WebSocketu řádně uzavírala pomocí posluchače události nebo jiné logiky na straně serveru.

async function handleRequest(request) {
	let webSocketPair = new WebSocketPair();
	let [client, server] = Object.values(webSocketPair);
	server.accept();

	server.addEventListener("close", () => {
		// This missing line would keep a WebSocket connection open indefinitely
		// and results in "The script will never generate a response" errors
		// server.close();
	});

	return new Response(null, {
		status: 101,
		webSocket: client,
	});
}

"Illegal invocation" errors

Chybová zpráva TypeError: Illegal invocation: function called with incorrect this reference může být zdrojem nejasností.

Obvykle to způsobí volání funkce, která volá this, ale hodnota this bylo ztraceno.

Například pokud máte obj objekt s obj.foo() metoda, jejíž logika závisí na this, provede metodu přes obj.foo(); zajistí, že this správně odkazuje na obj objekt. Přiřazení metody do proměnné, napříkladconst func = obj.foo; a volání takové proměnné, např. func(); by mělo za následek this je undefined. Je to proto, že this se ztrácí, když je metoda volána jako samostatná funkce. Toto je standardní chování v JavaScriptu.

V praxi se to často projevuje při destrukturalizaci objektů JavaScriptu poskytovaných za běhu, které mají funkce závislé na přítomnosti this, jako je ctx.

Následující kód způsobí chybu:

export default {
	async fetch(request, env, ctx) {
		// destructuring ctx makes waitUntil lose its 'this' reference
		const { waitUntil } = ctx;
		// waitUntil errors, as it has no 'this'
		waitUntil(somePromise);

		return fetch(request);
	},
};

Nepoužívejte destrukturalizaci, případně funkci znovu navažte na původní kontext, abyste se chybě vyhnuli.

Následující kód bude fungovat správně:

export default {
	async fetch(request, env, ctx) {
		// directly calling the method on ctx avoids the error
		ctx.waitUntil(somePromise);

		// alternatively re-binding to ctx via apply, call, or bind avoids the error
		const { waitUntil } = ctx;
		waitUntil.apply(ctx, [somePromise]);
		waitUntil.call(ctx, somePromise);
		const reboundWaitUntil = waitUntil.bind(ctx);
		reboundWaitUntil(somePromise);

		return fetch(request);
	},
};

Nelze provádět I/O jménem jiného požadavku

Uncaught (in promise) Error: Cannot perform I/O on behalf of a different request. I/O objects (such as streams, request/response bodies, and others) created in the context of one request handler cannot be accessed from a different request's handler.

Tato chyba nastává, když se pokusíte sdílet vstupně výstupní (I/O) objekty (například streamy, požadavky nebo odpovědi) vytvořené jedním vyvoláním vašeho Workeru v kontextu jiného vyvolání.

V Cloudflare Workers je každé volání zpracováváno nezávisle a má vlastní kontext provádění. Díky tomuto návrhu jsou požadavky navzájem izolované, což zajišťuje optimální výkon i bezpečnost. Pokud se pokusíte sdílet I/O objekty mezi různými voláními, tuto izolaci porušíte. Protože jsou tyto objekty vázané na konkrétní požadavek, ve kterém vznikly, přístup k nim z handleru jiného požadavku není povolen a vede k chybě.

Tuto chybu nejčastěji způsobuje pokus o uložení I/O objektu do mezipaměti, například Požadavek v globálním rozsahu a poté k ní přistoupit v následujícím požadavku. Pokud například vytvoříte Worker a spustíte následující kód v lokálním vývoji a odešlete Workeru rychle za sebou dva požadavky, můžete tuto chybu reprodukovat.

let cachedResponse = null;

export default {
	async fetch(request, env, ctx) {
		if (cachedResponse) {
			return cachedResponse;
		}
		cachedResponse = new Response("Hello, world!");
		await new Promise((resolve) => setTimeout(resolve, 5000)); // Sleep for 5s to demonstrate this particular error case
		return cachedResponse;
	},
};

Vyřešíte to tak, že v globálním rozsahu budete ukládat pouze data, nikoli samotný objekt I/O:

let cachedData = null;

export default {
	async fetch(request, env, ctx) {
		if (cachedData) {
			return new Response(cachedData);
		}
		const response = new Response("Hello, world!");
		cachedData = await response.text();
		return new Response(cachedData, response);
	},
};

Pokud potřebujete sdílet stav napříč požadavky, zvažte použití Durable Objects. Pokud potřebujete ukládat data do cache napříč požadavky, zvažte použití Workers KV.

Chyby při nahrávání Workeru

Tyto chyby nastávají při nahrání nebo úpravě Workeru.

Kód chyby Význam
10006 Kód vašeho Workeru se nepodařilo zpracovat.
10007 Worker nebo subdoména workers.dev nenalezeno.
10015 Účet nemá oprávnění používat Workers.
10016 Neplatný název Workeru.
10021 Chyba ověření. Viz Chyby ověření s podrobnostmi.
10026 Tělo požadavku se nepodařilo zpracovat.
10027 Nahraný Worker překročil Limity velikosti Workeru.
10035 Více současných pokusů o úpravu stejného zdroje
10037 Účet překročil počet povolené Workers.
10052 A binding se nahraje bez názvu.
10054 Proměnná prostředí nebo secret přesahuje limit velikosti.
10055 Počet proměnných prostředí nebo secrets překračuje limit/Worker.
10056 Binding nenalezeno.
10068 Nahraný Worker nemá zaregistrovaný žádný obslužné rutiny událostí.
10069 Nahraný Worker obsahuje obslužné rutiny událostí nepodporovaná Workers runtime.

Chyby ověření (10021)

Chybový kód 10021 zahrnuje všechny chyby, ke kterým dojde při pokusu o nasazení Workeru, kdy se Cloudflare následně pokusí načíst a spustit nejvyšší úroveň skriptu (vše, co proběhne před spuštěním obslužné rutiny vašeho Workeru obslužná rutina se vyvolá). Pokud se například pokusíte nasadit nefunkční Worker s neplatným JavaScriptem, který by vyvolal SyntaxError : Cloudflare váš Worker nenasadí.

Mezi konkrétní chybové stavy mimo jiné patří:

Script startup exceeded CPU time limit

To znamená, že v top-level scope vašeho Workeru provádíte práci, která trvá déle než limit doby spuštění (1 s) CPU času.

Script startup exceeded memory limit

To znamená, že v top-level scope vašeho Workeru provádíte práci, která alokuje více než limit paměti (128 MB) paměti.

Chyby runtime

Chyby runtime nastávají uvnitř runtime, nezobrazují chybovou stránku a nejsou viditelné pro koncového uživatele. Uživatel chyby runtime zjistí pomocí logů.

Chybová zpráva Význam
Network connection lost Selhání připojení. Zachyťte fetch nebo volání bindingu a zopakovat je.
Memory limit
would be exceeded
before EOF
Pokus o čtení streamu nebo bufferu, který by překročil limit paměti.
daemonDown Dočasný problém při vyvolání Workeru.

Identifikace chyb: Workers Metrics

Chcete-li zkontrolovat, zda vaše aplikace nemá výpadky nebo nevrací chyby:

  1. V dashboardu Cloudflare přejděte na Workers & Pages stránce.

    Přejděte na Workers & Pages ↗
  2. V Přehled, vyberte svého Workera a zkontrolujte jeho metriky.

Chyby Workeru

Chyby podle stavu volání graf zobrazuje počet chyb rozdělených do následujících kategorií:

Chyba Význam
Uncaught Exception Kód vašeho Workeru vyvolal během provádění výjimku JavaScriptu.
Exceeded CPU Time Limits Worker překročil limit CPU času nebo jiná omezení zdrojů.
Exceeded Memory Worker během provádění překročil limit paměti.
Internal V Workers runtime došlo k interní chybě.

Client disconnected by type graf zobrazuje počet chyb odpojení klienta rozdělených do následujících kategorií:

Client Disconnects Význam
Response Stream Disconnected Spojení bylo ukončeno ve fázi odloženého proxování v rámci zpracování požadavku Workeru. Obvykle se objevuje u déletrvajících spojení, jako jsou WebSockets.
Cancelled Klient se odpojil dříve, než Worker dokončil svou odpověď.

Ladění výjimek pomocí Workers Logs

Workers Logs je výkonný nástroj pro ladění vašich Workerů. Zobrazuje všechny historické protokoly generované vaším Workerem, včetně veškerých nezachycených výjimek, k nimž dojde během provádění.

Chcete-li najít všechny své chyby ve Workers Logs, můžete použít následující filtr: $metadata.error EXISTS. Zobrazí se tak všechny logy, které mají přiřazenou chybu. Filtrovat můžete také podle $workers.outcome abyste našli požadavky, které vedly k chybě. Můžete například filtrovat podle $workers.outcome = "exception" abyste našli všechny požadavky, které vedly k nezachycené výjimce.

Všechny možné hodnoty outcome najdete v Workers Trace Event reference.

Ladění výjimek z Wrangler

Chcete-li ladit svůj worker přes wrangler, použijte wrangler tail ke kontrole a opravě výjimek.

Výjimky se zobrazí pod exceptions pole v JSON vráceném wrangler tail. Jakmile zjistíte výjimku, která chyby způsobuje, nasaďte opravený kód znovu a dál sledujte logy, abyste potvrdili, že je problém vyřešen.

Nastavit protokolovací službu třetí strany

Worker může odesílat HTTP požadavky na jakoukoli veřejně dostupnou HTTP službu na internetu. Můžete použít například službu jako Sentry pro shromažďování chybových logů z Workeru, a to odesláním HTTP požadavku dané službě k nahlášení chyby. Podrobnosti o tom, jaký požadavek odeslat, najdete v dokumentaci API dané služby.

Při použití externí strategie protokolování mějte na paměti, že floating promises (promises, které nejsou ani await, return, ani nebyly předány do ctx.waitUntil()) se může po dokončení volání Workeru zrušit. Volání Workeru se nepovažuje za dokončené, dokud stále streamuje tělo odpovědi klientovi. Chcete-li spustit logování až po dokončení odpovědi, předejte promise požadavku do ctx.waitUntil(). Například:

export default {
	async fetch(request, env, ctx) {
		function postLog(data) {
			return fetch("https://log-service.example.com/", {
				method: "POST",
				body: data,
			});
		}

		// Without ctx.waitUntil(), the `postLog` function may or may not complete.
		ctx.waitUntil(postLog(stack));
		return fetch(request);
	},
};
addEventListener("fetch", (event) => {
	event.respondWith(handleEvent(event));
});

async function handleEvent(event) {
	// ...

	// Without event.waitUntil(), the `postLog` function may or may not complete.
	event.waitUntil(postLog(stack));
	return fetch(event.request);
}

function postLog(data) {
	return fetch("https://log-service.example.com/", {
		method: "POST",
		body: data,
	});
}

Shromažďování a ukládání Wasm core dumpů

Nakonfigurujte Wasm Coredump Service pro sběr coredumpů z vašich aplikací Rust Workers a jejich uložení do logů, Sentry nebo R2 pro analýzu pomocí wasmgdb. Přečtěte si blogový příspěvek pro další podrobnosti.

Při chybě přejít na origin

Použitím passThroughOnException(), aplikace Workers může přeposílat požadavky na váš origin server, pokud během běhu Workeru dojde k výjimce. Díky tomu můžete pomocí Workers přidat protokolování, sledování nebo jiné funkce, aniž by to omezilo funkčnost vaší aplikace.

ctx.passThroughOnException() přeposílá požadavky pro neošetřené výjimky ve vašem kódu Workeru, nikoli chyby z origin fetch(). Při proxování požadavků na origin obalte fetch(request) v try...catch a vrátí 5xx odpověď při selhání. Pokud zdrojový server fetch() vyvolá po spotřebování těla požadavku passThroughOnException() nemůže tělo znovu přehrát.

export default {
	async fetch(request, env, ctx) {
		ctx.passThroughOnException();
		// an error here will return the origin response, as if the Worker wasn't present
		return fetch(request);
	},
};
addEventListener("fetch", (event) => {
	event.passThroughOnException();
	event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
	// An error here will return the origin response, as if the Worker wasn’t present.
	// ...
	return fetch(request);
}