TOC

This article has been localized into Czech by the community.

Zpracování chyb:

Typy chyb a podmíněné zachycení

V předchozích článcích této kapitoly jsme mluvili o tom, jak můžeme v JavaScriptu zachytávat chyby pomocí bloků try..catch a try..catch..finally. Dokonce jsme mluvili o tom, jak můžeme sami vyhazovat chyby.

Doposud jsme se zabývali obecným typem chyby Error, na kterém jsou chyby v JavaScriptu založeny, ale ve skutečnosti existují specifičtější verze chyb v JavaScriptu. To se stává zvláště relevantním, když chcete rozlišovat mezi těmito různými typy chyb, o čemž budeme diskutovat v tomto článku. Také probereme, jak můžete vytvářet vlastní typy chyb, pro vyhazování specifických chyb odpovídajících typu problému.

Typy chyb

Obecný typ chyby Error vám vždy poskytne alespoň název a zprávu, která popisuje problém. Nicméně, na základě chyby, která nastala, může JavaScript použít specifičtější typ chyby, založený na obecném typu chyby Error, ale možná s více vlastnostmi a/nebo metodami.

Pro úplný seznam aktuálně dostupných typů chyb se prosím podívejte na tuto referenční stránku. Nyní mi dovolte ukázat vám jeden ze specifických typů chyb, které JavaScript může vyvolat: RangeError. Může nastat v mnoha různých situacích, ale jedním příkladem by bylo, pokud se pokusíte dělit BigInt nulou, takto:

let bigInt = BigInt(10000000000042);
let zero = BigInt(0);
alert(bigInt / zero);

Pokud spustíte příklad, uvidíte v konzoli chybu jako tato:

Uncaught RangeError: Division by zero

Jak vidíte, nyní se jedná o RangeError místo pouze obecného typu chyby Error. Můžeme to ověřit, když chybu zachytíme, a dokonce to můžeme použít k rozlišení mezi ostatními chybami.

Podmíněné zachytávání

Použitím techniky nazvané podmíněné zachytávání můžeme skutečně měnit náš postup podle toho, který typ chyby je vyvolán. To může být velmi užitečné při řešení složitějších případů, kde může dojít k několika různým typům chyb.

Víme, který typ chyby byl vyvolán buď podíváním se na její vlastnost name, která bude odpovídat typu chyby, nebo porovnáním ji s konkrétním typem pomocí operátoru instanceof. Zde je příklad, jak by podmíněné zachytávání mohlo vypadat:

try
{
	let bigInt = BigInt(10000000000042);
	let zero = BigInt(0);
	alert(bigInt / zero);
}
catch(error)
{
	if(error instanceof RangeError)
		alert("Something is wrong with the range!");
	else
		alert("Something else went wrong...");
}

Všimněte si, jak mohu snadno rozlišit, jakou akci chci provést, na základě typu chyby, která byla vyvolána.

Znovu vyhazování chyb

V posledním článku jsem ukázal, jak můžete vyhodit chybu, abyste volajícímu vašeho kódu dali přesnou indikaci toho, co se pokazilo. Ale někdy chcete zpracovat pouze konkrétní typ chyby a nechat ostatní typy na spotřebiteli vašeho kódu/funkce.

Pro situace jako tato můžeme kombinovat techniku podmíněného zachytávání s možností vyhazování chyb z příkazu catch - jinými slovy, můžeme znovu vyhodit chybu, aby byla odpovědnost za zpracování chyby předána dál. Zde je příklad:

function DivideBigInts(b1, b2)
{
	try
	{				
		return b1 / b2;
	}
	catch(error)
	{
		if(error instanceof RangeError)
			alert("Something is wrong with the range!");
		else
			throw error;
	}
}

DivideBigInts(BigInt(10000000000042), BigInt(0));

V tomto příkladu jsem vytvořil funkci pro dělení dvou BigIntů. Zachytává jakoukoli chybu, ale v případě, že dojde k chybě, která není RangeError, je chyba jednoduše znovu vyhozena. Samozřejmě to vyžaduje, abychom prováděli vlastní zpracování chyb, když funkci voláme.

Abychom viděli rozdíl, v tomto dalším příkladu jsem obrátil kontrolu chyb tak, že jsou znovu vyhozeny pouze RangeErrors, a poté jsem přidal blok try..catch pro řádek, kde funkci voláme - to je potřeba, protože voláme funkci, která může výjimku znovu vyhodit.

Také ukazuji, jak můžete přizpůsobit chybovou zprávu znovu vyhozením nové chyby, kde píšeme vlastní zprávu smíchanou se zprávou, kterou dostaneme z původní vyhozené chyby:

function DivideBigInts(b1, b2)
{
	try
	{				
		return b1 / b2;
	}
	catch(error)
	{
		if(error instanceof RangeError)
			throw new Error("A RangeError occurred. Message: " + error.message);
		else
			alert("Something went wrong...");
	}
}


try
{
	DivideBigInts(BigInt(10000000000042), BigInt(0));
} 
catch(error)
{
	alert(error.message);
}

Pokud tento příklad spustíte, uvidíte, že náš kód generuje RangeError, tato chyba je znovu vyhozena a poté zpracována v posledním bloku catch, mimo funkci. Zde zobrazíme chybu, kterou jsme obdrželi od funkce, s naší vlastní vlastní chybovou zprávou.

Vyhazování vlastních chyb

Jak jste viděli v předchozím příkladu, vyhodit chybu s vlastní zprávou je poměrně snadné - můžeme jednoduše vytvořit nový objekt Error a předat naši vlastní zprávu. Ale někdy to není dost, a stejně jako má JavaScript specializované typy chyb pro různé problémy, jak jsme viděli u typu RangeError, tak můžeme samozřejmě vytvořit i vlastní typ.

Abych vám ukázal, jak to funguje, vytvořím nový typ chyby rozsahu, který bude akceptovat minimální a maximální hodnotu, aby poskytl informativnější chybovou zprávu. Můžeme to udělat vytvořením třídy, která rozšiřuje třídu Error, takto:

class InformativeRangeError extends Error
{
	constructor(value, min, max)
	{
		super(`Value ${value} is not within the valid range - must be between ${min} and ${max}`);
		this.name = "InformativeRangeError";
	}
}

Všimněte si, jak naše třída InformativeRangeError přijímá tři parametry: skutečnou hodnotu, například jak ji zadal uživatel, stejně jako minimální a maximální hodnotu. Poté použijeme tyto tři hodnoty k vygenerování mnohem informativnější chybové zprávy, kterou předáme původnímu konstruktoru třídy Error pomocí klíčového slova super.

Zde je kompletní příklad, kde používáme třídu, vyhazujeme naši novou InformativeRangeError jako by to byla jen běžná chyba Error:

class InformativeRangeError extends Error
{
	constructor(value, min, max)
	{
		super(`Value ${value} is not within the valid range - must be between ${min} and ${max}`);
		this.name = "InformativeRangeError";
	}
}

let min = 1;
let max = 10;
let number = Number(prompt("Please enter a number:"));
if(number >= min && number <= max)
	alert("Thank you!");
else
	throw new InformativeRangeError(number, min, max);

Pokud tento příklad spustíte, zkuste zadat hodnotu mimo náš požadovaný rozsah (1-10), např. 14 - pokud se podíváte do konzole, uvidíte naši vlastní chybovou zprávu:

Uncaught InformativeRangeError: Value 14 is not within the valid range - must be between 1 and 10

Shrnutí

JavaScript nabízí různé typy chyb pro různé druhy problémů a pokud nejsou dostatečné, můžete snadno vytvořit vlastní typ chyby. Můžeme použít tyto různé typy, jak vestavěné, tak vlastní, k rozlišení toho, co děláme pro různé typy problémů pomocí podmíněného zachytávání a (volitelně) znovu vyhazováním chyb, které nechceme řešit na místě, kde nastanou.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!