Skip to content

Commit feb1f02

Browse files
committed
Fix mbeaudru#54 - More information about async / await error handling
1 parent 017aa82 commit feb1f02

File tree

1 file changed

+73
-38
lines changed

1 file changed

+73
-38
lines changed

readme.md

Lines changed: 73 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ When you struggle to understand a notion, I suggest you look for answers on the
9393
+ [Async Await](#async-await)
9494
- [Sample code](#sample-code-6)
9595
- [Explanation with sample code](#explanation-with-sample-code-2)
96+
- [Error handling](#error-handling)
9697
- [External resources](#external-resources-8)
9798
+ [Truthy / Falsy](#truthy--falsy)
9899
+ [Static Methods](#static-methods)
@@ -1276,15 +1277,13 @@ The purpose of async/await functions is to simplify the behavior of using promis
12761277

12771278
```js
12781279
async function getGithubUser(username) { // async keyword allows usage of await in the function and means function returns a promise
1279-
try { // this is how errors are handled with async / await
1280-
const response = await fetch(`https://api.github.com/users/${username}`); // "synchronously" waiting fetch promise to resolve before going to next line
1281-
return response.json();
1282-
} catch (err) {
1283-
alert(err);
1284-
}
1280+
const response = await fetch(`https://api.github.com/users/${username}`); // "synchronously" waiting fetch promise to resolve before going to next line
1281+
return response.json();
12851282
}
12861283

1287-
getGithubUser('mbeaudru').then(user => console.log(user)); // logging user response - cannot use await syntax since this code isn't in async function
1284+
getGithubUser('mbeaudru')
1285+
.then(user => console.log(user)) // logging user response - cannot use await syntax since this code isn't in async function
1286+
.catch(err => console.log(err)); // if an error is raised in our async function, we will catch it here
12881287
```
12891288

12901289
#### Explanation with sample code
@@ -1296,11 +1295,7 @@ getGithubUser('mbeaudru').then(user => console.log(user)); // logging user respo
12961295
```js
12971296
async function myFunc() {
12981297
// we can use await operator because this function is async
1299-
try {
1300-
return "hello world";
1301-
} catch(e) {
1302-
throw new Error();
1303-
}
1298+
return "hello world";
13041299
}
13051300

13061301
myFunc().then(msg => console.log(msg)) // "hello world" -- myFunc is turned into a promise because of async operator
@@ -1316,14 +1311,9 @@ Let's see how we could fetch a github user with promises first:
13161311

13171312
```js
13181313
function getGithubUser(username) {
1319-
return new Promise((resolve, reject) => {
1320-
fetch(`https://api.github.com/users/${username}`)
1321-
.then(response => {
1322-
const user = response.json();
1323-
resolve(user);
1324-
})
1325-
.catch(err => reject(err));
1326-
})
1314+
return fetch(`https://api.github.com/users/${username}`)
1315+
.then(response => response.json())
1316+
.catch(err => reject(err));
13271317
}
13281318

13291319
getGithubUser('mbeaudru')
@@ -1335,13 +1325,8 @@ Here's the *async / await* equivalent:
13351325

13361326
```js
13371327
async function getGithubUser(username) { // promise + await keyword usage allowed
1338-
try { // We handle async function errors with try / catch
1339-
const response = await fetch(`https://api.github.com/users/${username}`); // Execution stops here until fetch promise is fulfilled.
1340-
const user = response.json();
1341-
return user; // equivalent of resolving the getGithubUser promise with user value.
1342-
} catch (err) {
1343-
throw new Error(err); // equivalent of rejecting getGithubUser promise with err value.
1344-
}
1328+
const response = await fetch(`https://api.github.com/users/${username}`); // Execution stops here until fetch promise is fulfilled.
1329+
return response.json();
13451330
}
13461331

13471332
getGithubUser('mbeaudru')
@@ -1355,24 +1340,74 @@ For instance, if you need to get a token in order to be able to fetch a blog pos
13551340

13561341
```js
13571342
async function fetchPostById(postId) {
1358-
try {
1359-
const token = await fetch('token_url');
1360-
const post = await fetch(`/posts/${postId}?token=${token}`);
1361-
const author = await fetch(`/users/${post.authorId}`);
1362-
1363-
post.author = author;
1364-
return post;
1365-
} catch(e) {
1366-
throw new Error(e);
1367-
}
1343+
const token = await fetch('token_url');
1344+
const post = await fetch(`/posts/${postId}?token=${token}`);
1345+
const author = await fetch(`/users/${post.authorId}`);
1346+
1347+
post.author = author;
1348+
return post;
13681349
}
13691350

13701351
fetchPostById('gzIrzeo64')
13711352
.then(post => console.log(post))
13721353
.catch(err => console.log(err));
13731354
```
13741355

1375-
> **Note :** As you can see, *try / catch* are necessary to handle errors. But if you are making *express routes*, you can use a middleware to avoid error handling and have a very pleasant code to read. See [this article from Alex Bazhenov](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016) to learn more.
1356+
##### Error handling
1357+
1358+
Unless we add *try / catch* blocks around *await* expressions, uncaught exceptions – regardless of whether they were raised in the body of your *async* function or while it’s suspended during *await* – will reject the promise returned by the *async* function. [(Ref: PonyFoo)](https://ponyfoo.com/articles/understanding-javascript-async-await#error-handling).
1359+
1360+
With promises, here is how you would handle the error chain:
1361+
1362+
```js
1363+
function getUser() => { // This promise will be rejected!
1364+
return new Promise((res, rej) => rej("User not found !")
1365+
};
1366+
1367+
function getAvatarByUsername(userId) {
1368+
return new Promise((res, rej) =>
1369+
getUser(userId)
1370+
.then(user => res(user.avatar))
1371+
.catch(err => rej(err))
1372+
);
1373+
}
1374+
1375+
function getUserAvatar(username) {
1376+
return new Promise((res, rej) =>
1377+
getAvatarByUsername(username)
1378+
.then(avatar => res({ username, avatar }))
1379+
.catch(err => rej(err))
1380+
);
1381+
}
1382+
1383+
getUserAvatar('mbeaudru')
1384+
.then(res => console.log(res))
1385+
.catch(err => console.log(err)); // "User not found !"
1386+
```
1387+
1388+
If you forgot a *catch*, the error will be uncaught!
1389+
1390+
But with *async* functions, if an error is thrown in it's body the promise will reject:
1391+
1392+
```js
1393+
function getUser() => { // This promise will be rejected!
1394+
return new Promise((res, rej) => rej("User not found !")
1395+
};
1396+
1397+
async function getAvatarByUsername(userId) => {
1398+
const user = await getUser(userId);
1399+
return user.avatar;
1400+
};
1401+
1402+
async function getUserAvatar(username) {
1403+
var avatar = await getAvatarByUsername(username);
1404+
return { username, avatar };
1405+
}
1406+
1407+
getUserAvatar('mbeaudru')
1408+
.then(res => console.log(res))
1409+
.catch(err => console.log(err)); // "User not found !"
1410+
```
13761411
13771412
#### External resources
13781413

0 commit comments

Comments
 (0)