Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork3
Error handling with promises#195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Merged
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes fromall commits
Commits
Show all changes
2 commits Select commitHold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
10 changes: 5 additions & 5 deletions1-js/11-async/04-promise-error-handling/01-error-async/solution.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,13 @@ | ||
Odpověď zní: **ne, nespustí**: | ||
```js run | ||
new Promise(function(splň, zamítni) { | ||
setTimeout(() => { | ||
throw new Error("Ouha!"); | ||
}, 1000); | ||
}).catch(alert); | ||
``` | ||
Jak bylo řečeno v této kapitole, kolem kódu funkce je „implicitní`try..catch`“. Všechny synchronní chyby tedy budou ošetřeny. | ||
Zde však není chyba generována při běhu exekutoru, ale později. Příslib ji tedy nemůže zpracovat. |
8 changes: 4 additions & 4 deletions1-js/11-async/04-promise-error-handling/01-error-async/task.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
#Chyba ve funkci setTimeout | ||
Co myslíte? Spustí se `.catch`? Zdůvodněte svou odpověď. | ||
```js | ||
new Promise(function(splň, zamítni) { | ||
setTimeout(() => { | ||
throw new Error("Ouha!"); | ||
}, 1000); | ||
}).catch(alert); | ||
``` |
194 changes: 97 additions & 97 deletions1-js/11-async/04-promise-error-handling/article.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,205 +1,205 @@ | ||
#Ošetřování chyb pomocí příslibů | ||
Řetězy příslibů jsou vynikající při ošetřování chyb. Když je příslib zamítnut, řízení skočí do nejbližšího handleru pro zamítnutí. To je v praxi velice užitečné. | ||
Například v následujícím kódu jeURLpředané funkci`fetch`vadné (taková stránka neexistuje) a `.catch`ošetří chybu: | ||
```js run | ||
*!* | ||
fetch('https://takovy-server-neni.blabla') //zamítne | ||
*/!* | ||
.then(odpověď =>odpověď.json()) | ||
.catch(chyba => alert(chyba)) // TypeError: failed to fetch (textse může lišit) | ||
``` | ||
Jak vidíte,`.catch`nemusí být uvedeno okamžitě. Může se objevit až za jednou nebo i několika funkcemi `.then`. | ||
Nebo možná je se stránkou všechno v pořádku, ale odpověď není platnýJSON.Nejjednodušší způsob, jak zachytit všechny chyby, je přidat`.catch`na konec řetězu: | ||
```js run | ||
fetch('/article/promise-chaining/user.json') | ||
.then(odpověď =>odpověď.json()) | ||
.then(uživatel => fetch(`https://api.github.com/users/${uživatel.name}`)) | ||
.then(odpověď =>odpověď.json()) | ||
.then(uživatelGitHubu => new Promise((resolve, reject) => { | ||
letobrázek = document.createElement('img'); | ||
obrázek.src =uživatelGitHubu.avatar_url; | ||
obrázek.className = "promise-avatar-example"; | ||
document.body.append(obrázek); | ||
setTimeout(() => { | ||
obrázek.remove(); | ||
resolve(uživatelGitHubu); | ||
}, 3000); | ||
})) | ||
*!* | ||
.catch(chyba => alert(chyba.message)); | ||
*/!* | ||
``` | ||
Za normálních okolností se takové`.catch`vůbec nespustí. Jestliže však je kterýkoli z uvedených příslibů zamítnut (ať už kvůli síťové chybě, vadnému JSONu nebo čemukoli jinému),pak to zachytí. | ||
##Implicitní try..catch | ||
Kód příslibového exekutoru apříslibových handlerů má kolem sebe „neviditelné`try..catch`“. Jestliže nastane výjimka, bude zachycena a bude s ní zacházeno jako se zamítnutím. | ||
Například tento kód: | ||
```js run | ||
new Promise((splň, zamítni) => { | ||
*!* | ||
throw new Error("Ouha!"); | ||
*/!* | ||
}).catch(alert); // Error:Ouha! | ||
``` | ||
...Funguje přesně stejně jako tento kód: | ||
```js run | ||
new Promise((splň, zamítni) => { | ||
*!* | ||
zamítni(new Error("Ouha!")); | ||
*/!* | ||
}).catch(alert); // Error:Ouha! | ||
``` | ||
„Neviditelné`try..catch`“ okolo exekutoru automaticky zachytí chybu a promění ji v zamítnutý příslib. | ||
Děje se to nejen ve funkci exekutoru, ale i v jejích handlerech. Jestliže zavoláme `throw`uvnitř handleru `.then`, znamená to zamítnutý příslib, takže řízení skočí do nejbližšího chybového handleru. | ||
Následuje příklad: | ||
```js run | ||
new Promise((splň, zamítni) => { | ||
splň("ok"); | ||
}).then((výsledek) => { | ||
*!* | ||
throw new Error("Ouha!"); //zamítne příslib | ||
*/!* | ||
}).catch(alert); // Error:Ouha! | ||
``` | ||
To se děje pro všechny chyby, nejen pro ty, které vyvolal příkaz `throw`. Například pro programátorskou chybu: | ||
```js run | ||
new Promise((splň, zamítni) => { | ||
splň("ok"); | ||
}).then((výsledek) => { | ||
*!* | ||
blabla(); //taková funkce není | ||
*/!* | ||
}).catch(alert); // ReferenceError: blablanení definována | ||
``` | ||
Poslední`.catch`zachytává nejen výslovné zamítnutí, ale také neúmyslné chyby v uvedených handlerech. | ||
##Opětovné vyvolání | ||
Jak jsme se již zmínili, `.catch`na konci řetězu se podobá`try..catch`.Můžeme mít tolik handlerů`.then`, kolik chceme, a pak na konci použít jediný`.catch`, aby ošetřil chyby v nich všech. | ||
V běžném`try..catch`můžeme chybu analyzovat a případně ji opětovně vyvolat, pokud ji nemůžeme ošetřit. Totéž je možné i u příslibů. | ||
Jestliže zavoláme `throw`uvnitř `.catch`,pak řízení přejde do nejbližšího dalšího chybového handleru. A jestliže ošetříme chybu a normálně skončíme, pak bude pokračovat do nejbližšího dalšího úspěšného handleru `.then`. | ||
V následujícím příkladu`.catch`úspěšně ošetří chybu: | ||
```js run | ||
//výkon: catch -> then | ||
new Promise((splň, zamítni) => { | ||
throw new Error("Ouha!"); | ||
}).catch(function(chyba) { | ||
alert("Chyba je ošetřena, pokračuje se normálně"); | ||
}).then(() => alert("Další úspěšný handlerse spustil")); | ||
``` | ||
Zde blok `.catch`normálně skončí. Je tedy vyvolán další úspěšný handler`.then`. | ||
V následujícím příkladu vidíme s`.catch` opačnou situaci. Handler`(*)`zachytí chybu a nemůže ji ošetřit (např. proto, že umí ošetřit jenom`URIError`),takže ji opětovně vyvolá: | ||
```js run | ||
//výkon: catch -> catch | ||
new Promise((splň, zamítni) => { | ||
throw new Error("Ouha!"); | ||
}).catch(function(chyba) { // (*) | ||
if (chyba instanceof URIError) { | ||
//ošetří ji | ||
} else { | ||
alert("Tuto chybu nemohu ošetřit"); | ||
*!* | ||
throwchyba; //vyvolání této nebo jiné chyby skočí do dalšího catch | ||
*/!* | ||
} | ||
}).then(function() { | ||
/*toto se nespustí */ | ||
}).catch(chyba => { // (**) | ||
alert(`Nastala neznámá chyba: ${chyba}`); | ||
//nic nevrací=>běh pokračuje obvyklým způsobem | ||
}); | ||
``` | ||
Řízení skočí z prvního`.catch` `(*)`do dalšího`(**)`pod ním v řetězu. | ||
##Neošetřená zamítnutí | ||
Co se stane, když chyba není ošetřena? Například když zapomeneme přidat`.catch`na konec řetězu, například zde: | ||
```js untrusted run refresh | ||
new Promise(function() { | ||
takováFunkceNení(); //zde je chyba (taková funkce není) | ||
}) | ||
.then(() => { | ||
//úspěšné příslibové handlery, jeden nebo více | ||
}); //bez .catchna konci! | ||
``` | ||
V případě chyby bude příslib zamítnut a řízení by mělo skočit do nejbližšího zamítacího handleru. Tady však žádný není. Chyba tedy zůstane „viset“. Není zde žádný kód, který by ji ošetřil. | ||
V praxi, stejně jako u běžných neošetřených chyb v kódu, to znamená, že se něco ošklivě pokazilo. | ||
Co se stane, když nastane běžná chyba a není ošetřena pomocí`try..catch`?Skript spadne se zprávou na konzoli. Něco podobného se stane u neošetřených zamítnutí příslibů. | ||
Motor JavaScriptu tato zamítnutí sleduje a v takovém případě vygeneruje globální chybu. Můžete ji vidět na konzoli, pokud si spustíte uvedený příklad. | ||
V prohlížeči můžeme takové chyby zachytávat pomocí události `unhandledrejection`: | ||
```js run | ||
*!* | ||
window.addEventListener('unhandledrejection', function(událost) { | ||
//objekt událost má dvě speciální vlastnosti: | ||
alert(událost.promise); // [object Promise] -příslib, který vygeneroval tuto chybu | ||
alert(událost.reason); // Error:Ouha! -neošetřený chybový objekt | ||
}); | ||
*/!* | ||
new Promise(function() { | ||
throw new Error("Ouha!"); | ||
}); //není zde žádnécatch, které by tuto chybu ošetřilo | ||
``` | ||
Tato událost je součástí [standardu HTML](https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections). | ||
Jestliže dojde k chybě a není zde žádné`.catch`,spustí se handler`unhandledrejection`a obdrží objekt `událost` s informacemi o chybě, takže můžeme něco udělat. | ||
Z takových chyb se obvykle nelze zotavit, takže naše nejlepší cesta ven je informovat uživatele o problému a pravděpodobně hlásit tentoincidentserveru. | ||
V neprohlížečových prostředích, např. Node.js, existují jiné způsoby, jak vystopovat neošetřené chyby. | ||
##Shrnutí | ||
- `.catch`ošetřuje chyby všech druhů v příslibech: ať je to volání `zamítni()`nebo chyba vyvolaná v handleru. | ||
-Stejným způsobem zachytává chyby také `.then`, je-li zadán druhýargument (kterým je chybový handler). | ||
-Měli bychom`.catch`umisťovat přesně na místa, kde chceme ošetřovat chyby a víme, jak je ošetřit. Handler by měl analyzovat chyby (v tom nám pomáhají vlastní chybové třídy) a opětovně vyvolat ty, které nezná (možná jde o programátorské chyby). | ||
-Vůbec nepoužít`.catch`je v pořádku, jestliže neexistuje způsob, jak se z chyby zotavit. | ||
-V každém případě bychom měli mít handler události`unhandledrejection`(pro prohlížeče, analogický handler v jiných prostředích), abychom vystopovali neošetřené chyby a informovali o nich uživatele (a pravděpodobně náš server), aby naše aplikace nikdy „jen tak nespadla“. |
14 changes: 7 additions & 7 deletions1-js/11-async/04-promise-error-handling/head.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Oops, something went wrong.
Uh oh!
There was an error while loading.Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.